터미널에서 하나의 파일을 제외한 특정 확장자를 가진 파일 제거


36

이름이 "filename.gif"인 파일 하나를 제외하고 확장자가 .gif 인 모든 파일을 제거해야합니다. 터미널 에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

rm 명령 *.gif은 파일을 포함하여 모든 gif 파일을 제거합니다 filename.gif.

답변:


66

사용해야 할 간단한 솔루션은 다음과 같습니다.

mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif

.keep확장명에는 특별한 것이 없습니다 .gif. 파일 이름이 일시적으로 끝나지 않도록 확장 합니다.

파일 이름을 변경하지 않아야하는 경우 (그리고 이것이 중요한 스크립팅 상황이있는 경우) :

for X in *.gif; do
    if [ "$X" != "filename.gif" ]; then
        rm "$X"
    fi
done

또는 다음과 같이 더 짧게 작성할 수 있습니다.

for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done

find대신 사용하는 것이 좋습니다. 매우 강력한, 당신은 할 수 더 읽기 고려하고, 더 나은 핸들 과 같은 문자가 이상한 파일 이름 *그들 .

find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete

나는 -not가독성을 위해 연산자를 사용 했지만, GNU find를 사용하지 않거나 다른 스크립트로 배포하거나 다른 시스템에서 실행하려는 경우 POSIX 준수가 중요한 경우에는 !대신 연산자를 사용하십시오 .

find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete

한 가지 편리한 점은 find대소 문자를 구분하지 않는 명령을 쉽게 수정할 수 있으므로 확장자가있는 파일도 찾아서 삭제할 수 있다는 것입니다 .GIF.

find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete

검색 패턴 -iname대신 사용 했지만에 사용 하지 않았습니다 . 아마도 파일이 무엇인지 정확히 알고 확장명 뿐만 아니라 파일 이름의 다른 곳에서도 대체 대문자와 일치 합니다.-name*.giffilename.gif-iname

이러한 모든 솔루션 은 현재 디렉토리에있는 파일 만 삭제합니다 . 현재 디렉토리에 포함되지 않은 파일은 삭제하지 않으며 현재 디렉토리의 하위 디렉토리에있는 파일은 삭제하지 않습니다.

현재 디렉토리 내에 포함 된 모든 파일을 삭제하려면 (즉, 서브 디렉토리 및 해당 서브 디렉토리의 서브 디렉토리 등을 포함하여) 현재 디렉토리 또는 그 하위 디렉토리에 포함 된 파일을 삭제하려면 다음을 사용 find 하지 않고 사용하십시오 maxdepth -1.

find . -not -name 'filename.gif' -name '*.gif' -delete

이것에 조심하십시오!

로 다른 값을 설정할 수도 있습니다 -maxdepth. 예를 들어, 현재 디렉토리와 그 하위 및 손자에서 파일을 삭제하지만 더 깊은 것은 아닙니다.

find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete

-delete다른 표현을하기 전에 절대로 먼저 두지 마십시오 ! 당신은 내가 항상 -delete끝에 놓인 것을 볼 수 있습니다. 처음에 넣으면 먼저 평가되고 아래의 모든 파일 .(끝없는 .gif파일과 깊은 하위 하위 디렉토리의 파일 포함 .)이 삭제됩니다!

자세한 내용은 대한 매뉴얼 페이지를 참조 bash하고 sh이러한 예에서 사용되는 명령에 대한이 : mv, rm, [,와 (특히) find.


1
엘리야에게 감사합니다. 파일을 다른 형식으로 변환하고 다시 변환하는 첫 번째 방법과 비슷하게 수행했습니다. 그러나 그것은 조금 낙관적이고 부정한 것처럼 보였습니다. 나는 당신과 @efthialex가 제안한 두 번째 접근법을 좋아하고 그것을 지금 사용하고 있습니다. 감사!

1
@Marvis 이것이 귀하의 요구를 충족 시켜서 기쁩니다. 그건 그렇고,이 답변을 find다목적 인를 사용하여 다른 방법 (또는 방법 클래스)에 대한 정보로 확장했습니다 .
Eliah Kagan

3
자세한 답변에 감사드립니다 find.

1
상식 (move-delete-move) 답변의 경우 +1
tu-Reinstate Monica-dor du

Nit-Pick : find이상한 *루프 파일 이름을 for-loop보다 잘 처리 하는 방법은 무엇입니까? *큰 따옴표를 사용했기 때문에 for 루프는 파일을 잘 처리 합니다.
Flimm

28

당신이 사용하는 경우 bash(기본 쉘)는 extglob쉘 옵션을 사용하면 확장 된 패턴 일치 구문을 사용할 수 있습니다. 이를 활성화하려면 shopt내장 명령을 사용하십시오 .

shopt -s extglob

( .bashrc파일에 해당 줄을 포함 시킵니다.)

무엇보다도, 그것은 !()연산자에 대한 액세스 권한을 부여하며 , 이는 연산자 안에 있지 않은 패턴과 일치합니다. 당신의 목적을 위해 :

rm !(filename).gif

자세한 내용은 man bash"패턴 일치" 에서 확인할 수 있습니다 .


1
훌륭한 답변! bash 전용이므로 휴대용 스크립팅에는 적합하지 않지만 대화 형 작업 및 일부 스크립팅에는 적합하지 않습니다.이 방법은 가장 좋은 방법입니다. extglob활성화 해야하는 추가 복잡성을 가지고 있지만 비활성화되어 있으면 아무런 문제가 발생 하지 않습니다 (이 경우 작동하지 않습니다). 그리고 shopt -s extglob내 (또는 전역) 구성 파일 이 없어도 기본적으로 사용되는 것으로 보입니다 . 왜 그것이 바로 그것이 나를 위해 작동하는지에 대한 간단한 설명이 있다면, 당신은이 답변에 그것을 추가하고 싶을 것입니다; 또는 새로운 질문을 게시 할 수 있습니다.
Eliah Kagan

13

+ + 로 터미널 을 열고 다음을 입력하십시오.CtrlAltT

find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;

의 차이 -delete와는 -exec rm -vf {} \;두 번째 옵션과 함께, 당신은 때문에의 파일이 제거 된 볼 수있을 것입니다 -v플래그. -delete옵션 으로는 할 수없는 일입니다 . ( -name -delete파일 이름을 인쇄 할 것이지만 rm으로는 -v각 파일의 경우 보여준다 성공적 으로 삭제되었습니다.)


1

있다 GLOBIGNORE변수. 보낸 사람 man bash:

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.

따라서 간단한 방법은 GLOBGINORE문제의 파일 이름으로 설정 하는 것입니다.

$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png

따라서 귀하의 경우 :

GLOBIGNORE=filename.gif; rm *.gif

물론 GLOBIGNORE패턴이 포함되어 있으므로 패턴을 제외 할 때마다 사용할 수 있습니다.

$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png

장점 (?!)은 자동으로 제외 하고 일치하지 않도록 GLOBIGNORE설정 하면 다음 을 가능하게합니다 ....dotglob

The  GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern.  If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches.  The filenames ``.''  and ``..''  are  always  ignored
when  GLOBIGNORE is set and not null.  However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option,  so
all other filenames beginning with a ``.''  will match.  To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*''  one
of  the  patterns  in  GLOBIGNORE.  The dotglob option is disabled when
GLOBIGNORE is unset.

따라서 디렉토리의 모든 파일과 폴더 를 삭제하는 간단한 방법은 다음 과 같습니다.

GLOBIGNORE=.; rm -r *

이 활성화 된 이후로 *시작하는 파일 이름과 일치 하지만 또는 일치 하지 않으므로 부모 디렉토리에는 영향을 미치지 않습니다..GLOBIGNOREdotglob...

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