지정된 확장자를 가진 파일을 제외한 디렉토리의 모든 파일을 어떻게 나열합니까?


28

.txt , .pdf 및 기타 파일이 들어있는 폴더가 있다고 가정 하십시오. "기타"파일 (예 : 확장자가 .txt 또는 .pdf가 없는 파일)을 나열하고 싶습니다 . 이 작업을 수행하는 방법에 대한 조언이 있습니까?

주어진 확장자가없는 파일을 나열하는 방법을 알고 있습니다. 예를 들어 .txt 파일을 제외한 모든 파일을 나열하려면

find -not -iname "*.txt"

또는

ls | grep -v '\.txt$' | column

작동하는 것 같습니다. 그러나 .txt 파일 또는 .pdf 파일을 제외한 모든 것을 어떻게 나열 할 수 있습니까? 내가 몇 가지 논리적 인 종류의 "또는"을 사용할 필요가 보인다 findgrep.


2
숨겨진 도트 파일 의 경우 lsvs findvs globbing 동작 이 다를 수 있습니다.
jw013

1
명심해야 할 또 다른 사항 : find재귀와 같은 하위 디렉토리를 순회 ls합니다. -maxdepth 1와 함께 사용 하여 find보다 유사하게 동작하도록합니다 ls.
jw013

재귀가 없으므로 현재 디렉토리에 파일을 나열하십시오.
데이지

답변:


28

하나의 적절한 버전이 있다고 가정하면 ls가장 간단한 방법 일 수 있습니다.

ls -I "*.txt" -I "*.pdf"

모든 서브 디렉토리를 반복하려면 다음을 수행하십시오.

ls -I "*.txt" -I "*.pdf" -R

8
GNU ls옵션은 이식성이 없습니다.
bahamat

4
ls어쨌든 휴대용 스크립트에 속하지 않기 때문에 OP가 대화 형 사용 만 요구한다고 가정했습니다.
jw013

1
ls는 왜 휴대용이 아닌가? 그러면 무엇을 사용해야합니까?
Freedo

28

지원 찾기 -o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'

우선권을 가지려면 괄호가 필요합니다. 찾기는 많은 일을한다. 맨 페이지를 읽는 것이 좋습니다.

또는을 수행 할 수도 있습니다 grep(그러나 실제로 는의 출력을 구문 분석해서는 안됩니다ls )

ls | grep -Ev '\.(txt|pdf)$' | column

1
감사! 왜 출력을 구문 분석해서는 안 ls됩니까?
Andrew

6
@Andrew는 깨지기 쉽기 때문에 먼저 시작했습니다 (파일 이름에 줄 바꿈이있는 파일 이름을 고려하십시오. 둘째, 보통 더 쉬운 방법이 있기 때문입니다.
derobert

받는 사람 또한 find맨, 나는 진심으로 대한 유닉스 파워 툴 기사 추천 find등, docstore.mik.ua/orelly/unix3/upt/ch09_06.htmdocstore.mik.ua/orelly/unix3/upt/ch09_12.htm을
와일드 카드

인간에 대한 진술을 해독하는 것을 돕기 위해 :find . NOT ( *.txt OR *.pdf )
wisbucky

12

bash(으로 켜 글 로빙 확장 shopt -s extglob)의 글로브는 !(*.txt|*.pdf)작동합니다. 이 glob을 포함하여 (이에 국한되지는 않음) 파일 인수를 취하는 모든 명령에 직접 전달할 수 있습니다 ls.


1
+1이지만 하위 디렉토리가 있으면 해당 내용도 나열됩니다. 사용 -d하지 않도록한다 :ls -d !(*.txt|*.pdf)
legends2k

감사합니다. 여러 파일을 허용하는 구문을 정확하게 찾고있었습니다. 이것은 여기에 잘 맞습니다. stackoverflow.com/questions/216995/…
Freedo

6

에서 zshextendedglob:

print -rl -- *~*.(txt|pdf)

또는

print -rl -- ^*.(txt|pdf)

또는 kshglob(예, ksh globbing은 "bash extended globbing"이 아닙니다) :

print -rl -- !(*.txt|*.pdf)

도트 파일도 제외한다는 점을 기억하십시오.

ksh93에는 FIGNORE(mis) 기능이 있습니다.

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *


3

derobert가 제안한 것처럼 가장 좋은 방법은을 사용하는 것 find입니다. 그러나 실제로 다른 명령과 함께 파이프 라인에서 결과를 사용할 수 있습니다 .

GNU (및 일부 BSD) 는 NUL 문자로 끝나는 파일 이름을 인쇄하도록 지시 find하는 -print0술어를 지원합니다 .이 문자는 파일 이름에 허용되지 않는 문자이며 충돌이 발생하지 않습니다. 다른 명령은 NUL 을 입력 분리 자로 사용하도록 지시 할 수 있습니다 .

그중 가장 중요한 것은 GNU xargs이며, 이것은 지정한 명령을 실행하고 파일 목록을 명령 행 인수로 전달합니다. xargs -r0find와 함께 실행하려고합니다 -print0. 예를 들면 다음과 같습니다.

find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld

이름에 공백이나 인쇄 할 수없는 문자가있는 파일을 포함하여 모든 pdftxt 파일 의 긴 디렉토리 목록을 안전하게 인쇄합니다 .

tar다음과 같이 GNU와 함께 사용할 수도 있습니다 .

tar -zcf myarchive.tar.gz --null --files-from <(
  find . -type f ! -name \*.tar.gz -print0)

이름이 .tar.gz로 끝나지 않는 모든 파일의 tar.gz 파일을 빌드합니다.

rsync또한 -0다른 여러 가지 와 마찬가지로 매개 변수를 사용하여 null로 구분 된 파일을 허용 합니다. 그러나 xargs일반적으로 이러한 유형의 용도로 사용할 접착제입니다. 또는 find-exec기능 중 하나입니다 .


tar명령 예제는 좋은 것입니다. 그러나 대부분의 -exec경우 더 적합합니다.
와일드 카드

1

서브 디렉토리가없는 경우

ls !(*.pdf|*.txt)

작동해야합니다!

그러나

ls -I "*.pdf" -I "*.txt"

일반적인 방법입니다.


0

보완책으로, bash 호환 쉘을 사용하는 경우 GLOBIGNORE 변수를 사용하여 패턴 일치에서 결과를 제외 할 수 있습니다. 남자에게서 :

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

특별한 경우 :

sh$ (GLOBIGNORE='*.pdf:*.txt'; ls -d *)

대화식 쉘의 GLOBIGNORE 환경 변수를 변경하지 않기 위해 괄호를 사용하여 해당 명령을 하위 쉘로 실행하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.