타겟 검색에서 디렉토리 제외

타겟 검색에서 디렉토리 제외

검색은 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한 줄에 하나씩 쓰는 것과 동일 )-lprint -C1print -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 shman 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이 흐름 교체를 통합하는 방식입니다.

관련 정보