ls 명령 결과의 보수를 얻습니다.

ls 명령 결과의 보수를 얻습니다.

여러 파일이 있는 디렉토리가 있다고 가정해 보겠습니다. 모든 파일은 바이너리 파일(확장자가 선언되지 않은 파일)과 소스 파일( .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/에서 도입됨)에서 발견되지만 findPOSIX에서는 지정되지 않습니다. 또 다른 방법은 Stéphane이 자신의 의견에서 언급한 것처럼 찾기 작업을 사용하는 것입니다. 호출 횟수가 크게 줄어들기 때문에 형식을 사용하는 것을 기억하세요. (파일 이름을 끝에 넣을 수 있는 구문을 허용해야 합니다. 그렇지 않으면 래핑해야 합니다. 통화 중).findxargs-exec-exec command {} +commandcommandsh -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및 가 xargsNULL로 끝나는 문자열로 작업할 수 있는 경우 - 예를 들어 GNU 도구는 입니다).

답변2

에서는 ksh다음을 사용할 수 있습니다.

rm -- !(*.c|*.md)

bash이러한 와일드카드 확장은 after shopt -s extglobzshafter 에서도 사용할 수 있습니다 setopt kshglob.

다음은 zsh 기본 해당 항목입니다.

setopt extended_glob
rm -- ^(*.c|*.md)

!extglob에 있는 것은 "not"입니다. 원래 명령의 경우 다음과 같이 작성하는 것이 좋습니다.

rm -- *.c *.md

구문 분석된 출력은 ls신뢰할 수 없으며 일부 파일 이름에서 중단됩니다. 배쉬 위키를 참조하세요ls를 구문 분석하다.

관련 정보