찾기 검색에서 디렉토리 제외


12

검색 locate은 파일 시스템에서 경로 를 찾습니다.
종종 파일이나 디렉토리에만 관심있는 우선 순위를 알고 있습니다.
'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

두 번째는 아닙니다.

이 모호성은 긴 경로 목록을 읽기 어렵게 만들기 때문에 예를 들어에 대한 comman line 옵션을 사용하여 디렉토리를 필터링하는 것이 좋습니다 locate.

이와 같은 것이 존재합니까? 디렉토리에 대한 필터가 locate와 다른 경우에도?

적어도 스크립트를 사용하여 모든 파일 이름을 반복하여 확인할 수 있습니다. 느릴 수 있습니다.

답변:


3

zsh:

print -rl ${(0)^"$(locate -0 ...)"}(N.)

(0)매개 변수 확장 플래그입니다 NUL 문자에 분할 (우리가 사용으로 locate -0짧은) (ps:\0:).

를 사용 하여 배열 끝에 ^추가하는 대신 (N.)각 요소에 추가합니다.

(N.).정규 파일 만 일치하고 일치 N하지 않는 요소를 제거 하는 glob 한정자입니다 (존재하지 않거나 일반 파일이 아니거나 검사 할 수 없음). 대신 일반 파일 대신 디렉토리가 아닌 디렉토리를 일치 ^/시키는 .데 사용할 수도 있습니다 .

print -rl각 인수를 raw 로 별도의 에 인쇄합니다 .

zshglob 한정자를 사용할 수 있지만 여기에서는 파일 당 하나의 glob를 확장하므로 정렬 할 파일이 하나뿐이기 때문에 순서를 정하는 것에는 아무런 영향이 없습니다.

(마지막으로보고 된 마지막 파일 locate이 개행 문자 로 끝나는 경우 실패 할 수 있습니다 (모든 쉘에 명령 대체 기능 오류)).


3

이것은 다른 답변만큼이나 우아하지는 않지만 덜 비효율적입니다.

locate --regex --basename "xfce4-keyboard-overlay$" | 
        while IFS= read -r f; do [ -f "$f" ] && printf "%s\n" "$f"; done

(가독성을 위해 두 줄로 나)습니다). 위의 공백을 포함하는 이름을 처리합니다. 이 IFS=함께 이름을 처리하는 데 필요한 것 같다 후행 물론,은, 공백 및 -r역 슬래시를 처리 할 수 있습니다.

locate바꿈이 포함 된 경로 이름이 있으면 " 파이프 를 무언가로 연결"접근 방식이 실패 할 수 있습니다.


에 대한 자세한 내용은 IFS읽기, sh(1)또는 bash(1) (입력하여 man sh또는 man bashA * nix에서 스크립트 시스템으로, 및 / 또는 그것을 읽고 여기 , 여기 , 여기 , 및 / 또는 여기 ). 그런 다음 IFSBash 이해 : 행 단위로 읽기, 스택 교환 에서 IFS 로 (5 표 이상으로 답변에 집중) 여전히 충분하지 않은 경우 Greg의 WikiIFS 검색 결과 에서 IFS를 확인하십시오. Bash Hackers Wiki에서 (스택 교환이 아님).


while진술 후 "IFS ="에 대한 정보를 추가 할 수 있습니까?
robert

나는 그렇게했다.
G-Man, 'Reinstate

백 슬래시는 여전히 많은 에코 구현에서 문제가 될 것입니다. 임의의 데이터에 사용해야 printf합니다 .
Stéphane Chazelas

거기에 "--null"매개 변수를 사용하여 줄 바꿈 문제에 대한 해결책이 될 수 있습니다 locate귀하의 증대 read로 여기 제안 transnum.blogspot.ie/2008/11/...
로버트

@ StéphaneChazelas : 좋은 지적입니다. 결정된.
G-Man, 'Reinstate

2
locate --null --regex --basename "xfce4-keyboard-overlay$" |
  xargs -r0 sh -c 'find "$@" -prune ! -type d' sh

사실, 그것은보기보다 더 더럽지 만 ... 좋은 망설임. 그것이 의사 코드 인 것처럼 가장하자, 도움이됩니다. :)
Volker Siegel

1
@ Volker : 나쁘다는 것에 동의합니다 . 귀하의 예제에서 목록 /usr/local/share/xfce4-keyboard-overlay 과 모든 하위 디렉토리를 나열 합니다. -maxdepth 0도움 추가 .
G-Man, 'Reinstate

더 좋아진다 ... : D locate --regex --basename "xfce4-keyboard-overlay$" | xargs -I % sh -c "test -d % && echo %"
FloHimself

1
xargswith find를 사용 하는 것이 좋은 생각이었습니다. 견고하게 편집했습니다. 당신이 상관하지 않기를 바랍니다.
Stéphane Chazelas

1

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명령을 묶는 능력에 방해가되는 것 같습니다.


3
그 사람은 방금 내 컴퓨터를 재부팅했습니다 (파일이 있었고 /home/evil/$(reboot)/xfce4-keyboard-overlay어리석게도을 실행했습니다 root).
Stéphane Chazelas

2
@ StéphaneChazelas +1 루트로 "인터넷에서 랜덤 코덱"을 실행하는 용기;; (scnr)
Volker Siegel

0

내 두 센트 :

while IFS= read i; \
do \
  if [ -f "$i" ]; \
  then \
    echo "$i"; \
  fi; \
done < <(locate --regex --basename "xfce4-keyboard-overlay$")

이것은 G-Man이 프로세스 대체와 결합한 방식과 거의 비슷합니다.


사실,이 더 많거나 적은 방법입니다 내가 프로세스 대체와 함께 그것을했다, 마이너스 핸들 파일 이름 백 슬래시를 포함 또는 후행 공백 가지고 할 수있는 능력. 또한 질문 제목에 "제외 디렉토리"가 표시되며이 답변 에는 디렉토리 만 포함 됩니다.
G-Man, 'Reinstate

죄송합니다. 내 실수. 수정했습니다.
Tristan Storch

-1

당신은 무엇을 결합하는 경우 locatefilegrep? ...

$ for f in `locate --regex --basename "xfce4-keyboard-overlay$"`; do file $f; done | grep -vi directory

테스트하지는 않았지만 file모든 단일 경로 에 대한 프로세스를 생성하기 때문에 속도가 느릴 수 있다고 생각합니다 . 찾기에 대한 결과는 여러 줄이 있습니다. 현재 테스트에서 "gnome"을 검색하여 약 73000 개의 테스트 경로를 제공합니다.
Volker Siegel

2
@Volker : 그보다 더 나쁩니다 : $f파일 인 모든 파일에 대해 file프로그램이 해당 파일 을 열고 읽습니다 . 당신이해야 할 모든 일이있을 때 이것은 막대하게 비싸다 stat(). 또한… 이름에 "directory"가 포함 된 파일 (예 : "phone_directory")에 잘못된 결과가 표시됩니다. … ... ... ... ... (또한 for f in `…`; do …구문은 공백이 포함 된 이름을 처리 할 수 ​​없습니다.)
G-Man은 'Reinstate Monica'라고
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.