여러 파일이 있는 디렉토리가 있다고 가정해 보겠습니다. 모든 파일은 바이너리 파일(확장자가 선언되지 않은 파일)과 소스 파일( .c
확장자가 선언되어 있음)입니다. 나는 이렇게 한다:
$ ls
그리고 얻다:
README.md hello-world.c hello-world get-name.c get-name
.c
특정 확장자(예: 및 ) 를 가진 파일만 나열하고 싶습니다 .md
. 다음을 수행합니다.
ls *.c *.md
그것은 중요하지 않습니다!
하지만 지금 모든 파일을 삭제하고 싶다면 어떻게 해야 할까요?원하지 않는다.c
또는 확장 기능이 있는데 .md
어떻게 해야 하나요?
나는 다음과 같은 확장자를 가진 파일을 처리하는 방법을 알고 있습니다.
ls *.c *.md | xargs rm
하지만 해당 파일을 삭제하도록 명령줄에 어떻게 지시합니까?아니요내 기준에 맞는가?
답변1
사용 find
:
find -maxdepth 1 ! -name "*.c" -print0 | xargs -0 ...
-maxdepth
, , -print0
및 -r
는 일부 -0
구현(GNU/에서 도입됨)에서 발견되지만 find
POSIX에서는 지정되지 않습니다. 또 다른 방법은 Stéphane이 자신의 의견에서 언급한 것처럼 찾기 작업을 사용하는 것입니다. 호출 횟수가 크게 줄어들기 때문에 형식을 사용하는 것을 기억하세요. (파일 이름을 끝에 넣을 수 있는 구문을 허용해야 합니다. 그렇지 않으면 래핑해야 합니다. 통화 중).find
xargs
-exec
-exec command {} +
command
command
sh -c
또는 grep
출력ls
ls | grep -v "\.c$" | xargs ...
정규식을 사용하여 여러 확장자를 필터링할 수 있습니다.
... | grep -v "\.\(c\|md\)$" | ...
확장된 정규식을 사용하십시오:
... | grep -Ev "\.(c|md)$" | ...
고정 문자열 옵션을 사용하십시오(파일 이름 끝에서만 일치하지 않습니다!).
... | grep -vF ".c
.md" | ...
또는 더 많은 것을 연결하여 grep
:
... | grep -v "\.c$" | grep -v "\.md$" | ...
즉, find
이 -print0
옵션을 사용하면 이스케이프가 필요할 수 있는 파일 이름의 가능한 모든 문자를 처리할 수 있기 때문에 아마도 이것이 가장 좋은 옵션일 것입니다( find
및 가 xargs
NULL로 끝나는 문자열로 작업할 수 있는 경우 - 예를 들어 GNU 도구는 입니다).
답변2
에서는 ksh
다음을 사용할 수 있습니다.
rm -- !(*.c|*.md)
bash
이러한 와일드카드 확장은 after shopt -s extglob
및 zsh
after 에서도 사용할 수 있습니다 setopt kshglob
.
다음은 zsh 기본 해당 항목입니다.
setopt extended_glob
rm -- ^(*.c|*.md)
!
extglob에 있는 것은 "not"입니다. 원래 명령의 경우 다음과 같이 작성하는 것이 좋습니다.
rm -- *.c *.md
구문 분석된 출력은 ls
신뢰할 수 없으며 일부 파일 이름에서 중단됩니다. 배쉬 위키를 참조하세요ls를 구문 분석하다.