하나의 파일을 제외한 모든 파일 / 디렉토리 제거


244

많은 파일을 포함하는 디렉토리가 있습니다. file.txt를 제외한 모든 파일을 삭제하고 싶습니다. 어떻게해야합니까?

원하지 않는 파일을 개별적으로 제거하기에는 파일이 너무 많으며 이름이 너무 다양하여 *를 사용하여이 파일을 제외한 모든 파일을 제거 할 수 없습니다.

누군가 사용 제안

rm !(file.txt)

그러나 작동하지 않습니다. 다음을 반환합니다.

Badly placed ()'s 

내 OS는 Scientific Linux 6입니다.

어떤 아이디어?


13
당신이 유지하려는 하나를 이동 한 다음 다른 사람을 rm?
Olivier Dulac

5
@OlivierDulac이 질문에 우리가 질문을 지나치게 생각하지 않는 유일한 두 사람입니까?
Shadur

1
@shadur : 글쎄, 나는 그들과 관련이 있습니다 : oneliners는 매력적입니다 ... ^^
Olivier Dulac

1
고마워, 그리고 나는 한 줄 솔루션을 찾고있었습니다. 이 작업을 자주 수행해야하므로 파일을 계속 이동하는 데 시간이 너무 많이 걸립니다.
칸 투라

답변:


288

POSIXly :

find . ! -name 'file.txt' -type f -exec rm -f {} +

를 제외한 모든 일반 파일 (숨겨진 파일을 포함하여 재귀 적으로)을 제거합니다 file.txt. 디렉토리를 제거하려면, 변경 -type f-type d와 추가 -r로 옵션을 rm.

에서 bash사용하려면 rm -- !(file.txt)다음을 수행해야 extglob 가능 :

$ shopt -s extglob 
$ rm -- !(file.txt)

(또는 전화 bash -O extglob)

참고 extglob에서만 작동 bash및 Korn 쉘의 가족. 사용 rm -- !(file.txt)하면 Argument list too long오류 가 발생할 수 있습니다 .

에서 확장 글로브가 활성화 패턴을 무효화 zsh하는 ^데 사용할 수 있습니다 .

$ setopt extendedglob
$ rm -- ^file.txt

또는와 같은 구문을 사용 ksh하고 bash옵션 ksh_globno_bare_glob_qual사용 가능.


9
디렉토리를 지정하는 것이 좋습니다 (이 경우 전체 경로? 또는이 명령으로 현재 작업 디렉토리에서 시작하는 모든 파일을 삭제한다는 경고를 추가 할 수 있습니다 )? 또한 일반적 rm으로 echo rm대신 예제를 작성 하고 사람들이 원하는 것을 실제로 할 것이라고 확신 할 때만 에코를 꺼내도록 요청합니다. 그 외에는 완전한 답을 위해 +1
Olivier Dulac

11
나는 짧고 기억하기 쉬운 -delete대신에 제안 할 것이다-exec
Izkata

6
@Izkata : -delete는 POSIX에 의해 정의되지 않습니다.
cuonglm

5
파일 목록을 제외하는 방법?
Meysam

5
@Meysam-파일 목록을 처리하는 솔루션에 대한 내 대답을 참조하십시오. 그 외에 Gnouc의 find솔루션으로도 할 수 있습니다 ! \( -name one_file -o -name two_file \).
mikeserv

112

다른 방향으로 다른 방향 (파일 이름에 공백이없는 경우)

ls | grep -v file.txt | xargs rm

또는 (파일 이름에 공백이 있어도 작동합니다)

ls | grep -v file.txt | parallel rm

부터 man grep:

 -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX)

2
파일 이름에 공백이 있으면 작동하지 않습니다 ...
Matteo

1
Ciao @Matteo, 공백이있는 파일에서도 작동하지만 grep 패턴을 따옴표로 묶어야합니다 (예 :) ls | grep -v "a file with spaces.bin" | xargs rm. 이것은 정상적인 grep구문입니다.
Sebastian

1
@Sebastian 문제는 grep아니지만 rm. rm공백으로 구분 된 인수 목록을 가져옵니다. 시도 touch 'a b'; touch 'c d'; ls | grep -v 'a b' | xargs rm당신이 얻을 것이다 : rm: c: No such file or directoryrm: d: No such file or directory
마테오

1
예, 이것은 일반적인 문제입니다. 옵션보기 -print0에서 find-0의를 xargs. 여기에 해결 방법이 있지만 약간 불편합니다. find . -maxdepth 1 -type f | grep -v 'a b' | tr '\n' '\0' | xargs -0 rm. 그건 그렇고, gnu parallel는 이것을 잘 처리합니다 (거의 항상 xargs의 대체물로 사용합니다 :ls | grep -v 'a b' | parallel rm
Sebastian

1
공백 일뿐 만 아니라 공백과 줄 바꿈뿐만 아니라 따옴표로 묶는 문자 (싱글, 큰 따옴표 및 백 슬래시) 및 파일 이름으로 시작합니다 -.
Stéphane Chazelas

32

사본을 유지 보수하고 모든 항목을 삭제하며 사본을 복원하십시오.

{   rm -rf *
    tar -x
} <<TAR
$(tar -c $one_file)
TAR

한 줄로 :

{ rm -rf *; tar -x; } <<< $(tar -c $one_file)

그러나 여기에는 문자열을 지원하는 쉘이 필요합니다.


10
이것은 다소 마음이 부풀어 오른다.
vschum

2
@Derek-편집 내용을 참조하십시오.
mikeserv

2
그러나 이것이 도중에 중단되거나 다른 문제가 발생하면 파일이 사라집니다.
kasperd

2
@kasperd-아뇨. 상위 쉘이 실행 시간 rm과 사이에 사망하는 경우에만 해당됩니다 tar -x. rm원하는만큼 실패 할 수 있습니다.
mikeserv

2
다른 디렉토리로 옮기고 다시 옮기는 것이 더 효율적이지 않습니까? 파일의 내용 만 처리 할 필요는 없으며 경로 만 처리하면됩니다.
leonbloy

23

당신은 모두 이것을 너무 생각하고 있습니다.

cd ..
mv fulldir/file.txt /tmp/
rm -rf fulldir
mkdir fulldir
mv /tmp/file.txt fulldir/

끝난.

실제로 더 쉽게 편집하십시오 .

cd ..
ln fulldir/file.txt ./
rm -rf fulldir
mkdir -p fulldir
mv file.txt fulldir/

3
그것은 내 대답과 같은 것입니다. exce [pt는 dir에 대한 권한을 잃지 않습니다.
mikeserv

6
파일이 / tmp와 별도의 파일 시스템에있는 큰 파일이고 파일 시스템의 루트에서 모든 것을 제거하려는 경우 안전한 곳으로 옮기는 것이 옵션이 아닐 수 있습니다.
Johnny

1
이것이 가장 간단한 대답입니다.
Ben Liyanage

17

내 Scientific Linux 6 OS에서는 다음과 같이 작동합니다.

shopt -s extglob
rm !(file.txt)

또한 가상 머신에 데비안 32 비트가 설치되어 있습니다. 위의 기능은 작동하지 않지만 다음은 작동합니다.

find . -type f ! -name 'file.txt' -delete

1
find내가 준 솔루션이 효과가 없다는 것을 의미 합니까?
cuonglm

"작동하지 않았습니다"또는 "작동하지 않습니다". 예, 찾기 솔루션도 작동합니다. 감사.
Kantura

1
좀 더 자세하게 만들 수 있습니까? "작동하지 않는 방법은 무엇입니까? 다른 파일을 제거하지 않거나 제거하거나 다른 것을 제거 file.txt합니까?"
cuonglm

데비안 OS에서 "$ rm! (file.txt)"는 "잘못된 위치 () '를 반환합니다. 그래서 "$ shopt -s extglob"을 시도했지만 "shopt : Command not found"가 반환되었습니다. 그런 다음 "찾기"솔루션을 시도했습니다. 작동합니다.
Kantura

1
아, 물론 작동하지 않습니다. 내장 shopt되지 않습니다 tcsh.
cuonglm

10

rm !("file.txt")대신에 사용rm !(file.txt)


4
그것은 전혀 차이가 없습니다. 여기서 문제는 OP가 1)이 형식을 지원하는 셸을 사용하지 않고 2) bash에서도 활성화해야한다는 것입니다 shopt -s extglob. 어쨌든, 간단한 파일 이름을 인용해도 아무런 차이가 없었습니다.
terdon

1
utils 폴더 만 유지하려면
-rm

7

다른 답변을 제공하기 위해 rm폴더를 삭제하지 않는 기본 동작을 사용할 수 있습니다 .

mkdir tmp && mv file.txt tmp  # create tmp dir and move files there
rm                            # delete all other files
mv tmp/* . && rm -rf tmp      # move all files back and delete tmp dir

1

이 방법은 매우 간단하고 작동하며 특별한 확장이 필요하지 않습니다.

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