디렉토리에서 일부를 제외한 모든 파일을 제거하십시오.


215

를 사용할 때 sudo rm -r다음을 제외한 모든 파일을 어떻게 삭제할 수 있습니까?

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt


1
이이 질문을 읽을 수있는 두 가지 방법이 있으며, 기존의 대답은 모두 해석을 포함 :이든 : (a) 지정된 이름을 가진 파일 보존 을 직접 대상 디렉토리와 위치를 -로 rm -r의미 - 서브 디렉토리를 포함하여 다른 삭제 모든 것을, -가 포함 된 경우에도 지정된 이름의 파일; OR : (b) 대상 디렉토리의 전체 하위 트리를 순회하고 각 디렉토리에서 나열된 이름을 가진 파일을 제외한 모든 파일을 삭제합니다.
mklement0

답변:


219
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

-type ffind를 지정하지 않으면 find는 원하지 않는 디렉토리도 나열합니다.


또는 매우 유용한 조합을 사용하는보다 일반적인 솔루션 find | xargs:

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --

예를 들어, 현재 디렉토리에서 비 txt 파일을 모두 삭제하십시오.

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

print0-0삭제되어야하는 파일명 중 어느 하나의 공간이 있으면 조합이 필요하다.


2
xargs의 텍스트 크기 제한이있는 것 같습니다
frazras

26
여러 패턴을 삭제하는 방법 :find . -type f -not -name '*ignore1' -not -name '*ignore2' | xargs rm
Siwei Shen 申思维

5
디렉토리는 어떻습니까? 모든 파일을 삭제하지만 폴더를 제거합니까?!
orezvani

31
"| xargs rm"대신 find는 -delete 매개 변수를 사용합니다.
Emil Stenström

1
-print0 | xargs -0 rm --당신 대신에-delete
Andy

151
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

extglob (Extended Pattern Matching)은 BASH에서 활성화해야합니다 (활성화되지 않은 경우).

shopt -s extglob

2
내가 할 때 "예기치 않은 토큰`( '"근처에 구문 오류가 발생합니다 shopt -s extglob; rm -rf !(README|LICENSE). 이유가 무엇입니까?
Dennis

@nic 기억 나지 않습니다. 죄송합니다. 아마도 옵션 find과 함께 사용했을 것입니다 -delete.
데니스

이것은 나를위한 최적의 솔루션이며 shopt 내부 필요없이 내 우분투 12.04.4 LTS에서 기본적으로 작동
xtian

3
@nic, @Dennis : 구문 오류가 아닌 다른 무언가 제안 bash하였다, 예를 들어 dash, extglob지원되지 않습니다. 그러나 대화식 bash 쉘에서 명령은 다른 이유로 언급 된대로 작동하지 않습니다. 짧게 말하면 : shopt -s extglobBY ITSELF로 실행 ; 성공적으로 활성화 shopt extglob되면 (로 확인 ) 실행하십시오 rm -rf !(README|LICENSE). ( extglob아직 활성화되지 않았지만 명령이 실행되기 전에 기록 확장에!(...) 의해 평가됩니다 . 실패 할 가능성이 있기 때문에 NEITHER 명령이 실행되고 절대 켜지지 않습니다.)extglob
mklement0

2
@nic, @Dennis, @ mklement0 : .sh 파일 (#! / bin / bash) 내에서 명령을 실행할 때 "예기치 않은 토큰 근처의 구문 오류"와 동일한 문제가 있었지만 명령에서 실행할 때는 아닙니다. shopt -s extglob명령 줄 인터페이스에서 실행하는 것 외에도 스크립트 파일 내에서 다시 실행해야한다는 문제가 해결되었습니다.
Ahresse

41

find . | grep -v "excluded files criteria" | xargs rm

현재 디렉토리의 모든 파일을 나열한 다음 기준과 일치하지 않는 모든 파일을 나열하고 (디렉토리 이름과 일치하는지 확인한 후) 제거하십시오.

업데이트 : 편집 내용에 따라 나열된 파일을 제외하고 현재 디렉토리에서 모든 것을 삭제하려면 다음을 사용할 수 있습니다.

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup

백업 디렉토리를 생성하고 /tmp_backup(루트 권한을 가지고 있습니까?), 디렉토리에 나열된 파일을 이동하고, 현재 디렉토리의 모든 것을 재귀 적으로 삭제합니다 (당신은 올바른 디렉토리에 있다는 것을 알고 있습니까?) 현재 디렉토리로 돌아가서 /tmp_backup마지막으로 삭제/tmp_backup .

루트에서 백업 디렉토리를 선택합니다. 루트에서 모든 항목을 반복적으로 삭제하려고하면 시스템에 큰 문제가 발생하기 때문입니다.

분명히 이것을하는 더 우아한 방법이 있지만, 이것은 매우 간단합니다.


2
예를 들어 중간 라텍스 파일을 청소하는 등 egrep 과도 잘 작동합니다.find . | egrep -v "\.tex|\.bib" | xargs rm
mtsz

놀라운 명령! 디렉토리를 제거하기 위해 rm -r로 변경
Aris

1
제외 된 기준 이외의 현재 디렉토리에서 모든 항목을 삭제하려는 경우 : find . -maxdepth 1 | grep -v "exclude these" | xargs rm -r불필요하게 디렉토리로 드릴 다운 할 필요가 없으므로 훨씬 빠르게 작동합니다.
billynoah

다시 find파이프 라인 : 효율성 문제는 제쳐두고 (3 개의 명령은 find단독으로 수행 할 수있는 작업에 사용됨 ) 공백이 포함 된 파일 이름에서 의도 한대로 작동하지 않으며 잠재적으로 잘못된 파일을 삭제합니다.
mklement0

"저장 될"파일을 다른 위치 ( /tmp_backup) 에 저장하는 명령 은 사용자의 관점 에서 파일을 다시 가져 오기 위해 어디를 찾아야하는지 알지 못하면 모든 파일이 사라졌습니다. . 이런 이유로 저는 이런 유형의 전략을 선호하지 않습니다.
Craig McQueen


19

Bash에서 GLOBIGNORE 환경 변수를 사용할 수 있습니다.

php와 sql을 제외한 모든 파일을 삭제하고 싶다면 다음을 수행하십시오.

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

이와 같이 GLOBIGNORE를 설정하면 "ls *"또는 "rm *"와 같은 와일드 카드에서 php 및 sql이 무시됩니다. 따라서 변수를 설정 한 후 "rm *"을 사용하면 txt 및 tar.gz 파일 만 삭제됩니다.


6
+1; GLOBIGNORE변수 설정 및 복원에 대한보다 간단한 대안 은 서브 쉘을 사용하는 것입니다.(GLOBIGNORE='*.php:*.sql'; rm *)
mklement0

19

하위 쿼리 목록을 사용하는 것을 선호합니다.

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v, --invert-match 비 일치 행 선택

\| 분리 기호


1
우아한 솔루션
Joshua Salazar

9

아무도 그것을 언급하지 않았기 때문에 :

  • 삭제하고 싶지 않은 파일을 안전한 장소에 복사하십시오
  • 모든 파일을 삭제
  • 복사 한 파일을 다시 제자리로 이동

2
다시 복사 한 후 권한을 관리해야하기 때문에 더 복잡합니다.
Romulus

2
@RemusAvram 사용 권한 이 cp있거나없는 적절한 스위치를 사용할 수 있습니다 rsync. 어쨌든, 이것은 OP에 대한 답변으로 여기에 자리 잡고있는 대체 방법 (제안으로 제공됨)입니다.
gniourf_gniourf 오전

보유 할 파일이 다른 프로세스에서 활발하게 사용되고있는 많은 상황에서 이는 적절하지 않을 수 있습니다. 제거해야 할 파일 중 일부는 단지 작은 하위 집합이며 많은 파일이 관련되어 있습니다.
codeforester 2018 년

@codeforester : 물론입니다. 그러나 적절한 상황이 있지만 실제로는 귀하의 의견의 요점을 실제로 보지 못합니다 :).
gniourf_gniourf

6

이것에 대한 for 루프를 작성할 수 있습니다 ... %)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;

6

OP에 약간 늦었지만 Google을 통해 훨씬 나중에 여기에 오는 사람에게는 유용 할 것입니다 ...

@awi의 답변을 찾았으며 @Jamie Bullock의 -delete에 대한 의견이 정말 유용합니다. 최소한의 입력으로 매번 다른 파일 이름 / 유형을 무시하고 다른 디렉토리에서이를 수행 할 수있는 간단한 유틸리티 :

rm_except (또는 원하는 이름)

#!/bin/bash

ignore=""

for fignore in "$@"; do
  ignore=${ignore}"-not -name ${fignore} "
done

find . -type f $ignore -delete

예를 들어 텍스트 파일과 foo.bar를 제외한 모든 것을 삭제하려면 :

rm_except *.txt foo.bar 

@mishunika와 비슷하지만 if 절이 없습니다.


5

zsh내가 사용 하는 것이 좋습니다.

rm -rf ^file/folder pattern to avoid

extended_glob

setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)

4

그것을 시도하는 것은 다음과 같이 작동했습니다.

rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)

그러나 공백이있는 이름은 항상 그렇습니다. Virtualbox\ VMs대신 따옴표로 시도했습니다 . 항상 해당 디렉토리 ( Virtualbox VMs)를 삭제 합니다.


파일에는 작동하지 않습니다. rm !(myfile.txt)myfile.txt
khaverim 님이

실행해야 shopt -s extglob@의 pl1nk 지적 첫째로
zhuguowei

네, 아주 (글 로빙 확장 된 활성화에 중요 extglob을 : 실험실에서 몇 맥을 통해, 나는 매일 정기적으로이 일을하고 bash는) shopt -s extglob다음과 cd /Users/alumno/마지막으로 rm -rf !(Applications|Virtualbox*VMs|Downloads|Documents|Desktop|Public|Library) 연장 글 로빙에 대한 읽기 여기
juanfal

4

다만:

rm $(ls -I "*.txt" ) #Deletes file type except *.txt

또는:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf

권장하지 않습니다. 파싱 ls출력이 문제가 될 수 있습니다. 자세한 내용은 여기 를 참조하십시오.
RJ

2

파일을 불변으로 만듭니다. 루트조차도 삭제할 수 없습니다.

chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *

다른 모든 파일이 삭제되었습니다.
결국 변경 가능하도록 재설정 할 수 있습니다.

chattr -i *

0

이것은 @ siwei-shen의 의견과 비슷하지만 -o여러 패턴을 수행 하려면 플래그가 필요합니다 . -o플래그는 '또는'을 의미

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm


0

두 개의 명령 시퀀스로이를 수행 할 수 있습니다. 먼저 제외하지 않으려는 파일 이름으로 배열을 정의하십시오.

files=( backup.tar.gz script.php database.sql info.txt )

그런 다음 제외하려는 디렉토리의 모든 파일을 반복하여 파일 이름이 제외하지 않을 배열에 있는지 확인하십시오. 그렇지 않으면 파일을 삭제하십시오.

for file in *; do
  if [[ ! " ${files[@]} " ~= "$file"  ]];then
    rm "$file"
  fi
done

정규 표현식 비교가 잘못되었습니다. 이름이 보호 된 파일 중 하나의 하위 문자열 인 파일을 유지합니다 (주변 공간은 다소 완화하지만 파일 이름에는 공백이 포함될 수 있음). 모든 파일의 배열을 수집 한 다음 해당 배열에서 제외 할 파일을 빼고 나머지 파일을 제거해야합니다.
tripleee

-1

아무도 이것을 아직 언급하지 않았기 때문에 특정 경우에는 다음과 같습니다.

OLD_FILES=`echo *`
... create new files ...
rm -r $OLD_FILES

(또는 그냥 rm $OLD_FILES )

또는

OLD_FILES=`ls *`
... create new files ...
rm -r $OLD_FILES

shopt -s nullglob일부 파일이 있거나없는 경우 사용해야 할 수 있습니다.

SET_OLD_NULLGLOB=`shopt -p nullglob`
shopt -s nullglob
FILES=`echo *.sh *.bash`
$SET_OLD_NULLGLOB

nullglob없이 echo *.sh *.bash 당신 "a.sh b.sh * .bash"를 제공 할 수 있습니다.

( OSX에서는 작동하지 않지만 이 답변을 선호 합니다. )


Leonardo Hermoso의 기존 답변은 버그를 줄 이면서이 작업을 수행합니다. 공백이있는 파일 이름의 경우 실패합니다. 배열을 사용하면 특정 문제를 우아하게 해결할 수 있습니다 (또한 일반적으로 피해야 할 개인 변수에 대문자를 사용하지 않는 것이 중요합니다).
tripleee

-3

직접 명령을 사용하는 대신 필요한 파일을 현재 디렉토리 외부의 임시 디렉토리로 이동하십시오. 그런 다음 사용하여 모든 파일을 삭제 rm *하거나rm -r * .

그런 다음 필요한 파일을 현재 디렉토리로 이동하십시오.


보유 할 파일이 다른 프로세스에서 활발하게 사용되고있는 많은 상황에서 이는 적절하지 않을 수 있습니다. 제거해야 할 파일 중 일부는 단지 작은 하위 집합이며 많은 파일이 관련되어 있습니다.
codeforester 2018 년

-3

file.name을 제외한 모든 것을 제거하십시오.

ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf

2
디렉토리 / 파일에 공백이 있거나 이상한 문자가 있으면 데이터가 손실 될 수 있습니다. ls를 구문 분석해서는 안됩니다. mywiki.wooledge.org/ParsingLs
RJ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.