검색은 locate
파일 시스템에서 경로를 찾습니다.
종종 당신은 파일이나 디렉토리에만 관심이 있다는 것을 선험적으로 알고 있습니다.
"찾기" 검색은 일반적으로 많은 결과를 반환합니다. 결과에 한 가지 유형만 포함하면 출력을 줄이는 데 도움이 되므로 유용할 수 있습니다.
그러나 파일이나 디렉토리를 무시하는 것에 대한 더 흥미로운 주장이 있습니다. 왜냐하면 결과 경로 목록이 이론상뿐만 아니라 모호할 수 있기 때문입니다.
다음 예는 실제 사례이며 드문 일이 아닙니다.
$ locate --regex --basename "xfce4-keyboard-overlay$"
/usr/local/bin/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay
좋아, 뭔가 찾았어! 하지만... 파일인가요, 아니면 디렉토리인가요?
$ file /usr/local/bin/xfce4-keyboard-overlay
/usr/local/bin/xfce4-keyboard-overlay: bash script
그럼 여기 파일이 있습니다...
$ file /usr/local/share/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay: directory
두 번째는 그렇지 않습니다.
이러한 모호함은 긴 경로 목록을 읽기 어렵게 만들므로 locate
.
그런 것이 존재하나요? 디렉터리 필터링이 타겟팅과 별개인데도?
최소한 스크립트를 사용하여 모든 파일 이름을 반복하여 확인할 수 있습니다. 이는 느릴 수 있습니다.
답변1
그리고 zsh
:
print -rC1 ${(0)^"$(locate -0 ...)"}(N.)
(0)
는 매개변수 확장 플래그로 NUL 문자로 구분되며(사용한 대로 locate -0
) 의 약어입니다 (ps:\0:)
.
의 경우 배열 끝에 추가하는 ^
대신 각 요소에 추가합니다.(N.)
(N.)
.
일반 파일과만 일치하고 N
일치하지 않는 경우(존재하지 않거나 일반 파일이 아니거나 확인할 수 없는 경우) 요소를 제거하는 glob 한정자입니다 . 일반 파일 대신 디렉터리가 아닌 항목을 일치시키기 ^/
위해 대체를 사용할 수도 있습니다 . .
또는 -.
파일 유형을 결정하십시오.심볼릭 링크 해결 후(일치에 일반 파일에 대한 심볼릭 링크를 포함합니다).
print -rC1
각 매개변수 인쇄날것의olumn 에 ( 인쇄할 항목이 없고 아무것도 출력하지 않고 빈 줄을 인쇄한다는 점을 제외하면 1
C
한 줄에 하나씩 쓰는 것과 동일 )-l
print -C1
print -l
zsh
모든 전역 한정자를 사용할 수 있지만주문하다여기서는 파일당 glob을 확장하므로 아무런 효과가 없습니다. 따라서 정렬할 파일당 하나만 있습니다.
어떤 파일이 실행 파일/디렉터리/기호 링크/소켓인지 더 잘 식별하려면... 결과 파일을 매개 변수로 전달하여 ls -F
일부 */@=
... 접미사를 추가할 수도 있습니다.
이는 GNU 도구 및 Bourne과 유사한 쉘을 가정합니다.
elocate() {
locate -0e "$@" |
sort -z |
xargs -r0 ls --quoting-style=shell --color=always -Fd1U |
less -FIXR
}
모호함을 피하기 위해 파일 이름을 쉘 스타일로 인용하고 유형을 표시하기 위해 접미사를 추가하여 컬러 버전과 페이지 버전을 모두 제공하는 함수 elocate
가 정의됩니다 .locate
답변2
이것은 다른 답변만큼 우아하지 않지만 아마도 덜 효율적일 것입니다.
locate --regex --basename "xfce4-keyboard-overlay$" |
while IFS= read -r f; do [ -f "$f" ] && printf "%s\n" "$f"; done
(가독성을 위해 두 줄로 나눕니다.) 위의 내용은 공백이 포함된 이름을 처리합니다. IFS=
이름을 다루는 것이 필요할 것 같습니다.뒤따라물론 공백을 사용하면 -r
백슬래시도 처리할 수 있습니다.
locate
"무언가를 파이프로 연결하자" 접근 방식은 개행 문자가 포함된 경로 이름이 있는 경우 실패할 가능성이 높습니다.
자세한 내용은 *nix 시스템에서 또는 를 입력 하거나 IFS
읽어보십시오 .sh(1)
bash(1)
man sh
man bash
여기,
여기,
여기,그리고/또는여기). 그럼 읽어봐IFS에 대해 알아보기
그리고Bash: IFS를 사용하여 한 줄씩 읽기Stack Exchange에서(5표 이상 투표한 답변을 따르세요) 아직 충분하지 않다면 확인해 보세요.Greg Wiki의 IFS
그리고Bash Hackers Wiki의 IFS 검색 결과(스택 교환이 아님)
답변3
xargs
-L 1
또는 인수를 지정하면 각 행에 대해 명령이 반복됩니다 -i
.
$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i bash -c '(test -d "{}" && echo "{}")'
물론 각 파일에 대해 새 셸을 시작하지만 멋지고 컴팩트하다는 장점이 있습니다.
편집하다:이 답변은 각 파일에 대해 새 셸을 시작하기 때문에 만족스럽지 않습니다. 이는 두 가지 프로세스만 수행해야 합니다.
$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i echo 'test -d "{}" && echo "{}"' | bash
물론 인터프리터를 완전히 종료하지 않는다면 좋겠지만, xargs
명령을 연결하는 기능은 제한되어 있는 것 같습니다.
답변4
내 2센트:
while IFS= read i; \
do \
if [ -f "$i" ]; \
then \
echo "$i"; \
fi; \
done < <(locate --regex --basename "xfce4-keyboard-overlay$")
이것이 G-Man이 흐름 교체를 통합하는 방식입니다.