Unix : 파일에 나열된 파일을 삭제하는 방법


92

삭제할 파일 마스크 목록이 포함 된 긴 텍스트 파일이 있습니다.

예:

/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php

삭제해야합니다. rm`cat 1.txt`를 시도했는데 목록이 너무 깁니다.

이 명령을 찾았지만 목록에서 폴더를 확인할 때 일부 폴더에는 여전히 파일이 있습니다. xargs rm <1.txt수동 rm 호출은 이러한 폴더에서 파일을 제거하므로 권한에 문제가 없습니다.


8
6 년이 지났음에도 불구하고 답변 중 하나를 받아들이시겠습니까? 이렇게하면 질문이 해결 된 것으로 표시되고 다른 사용자에게도 도움이됩니다.
MERose

답변:


114

이것은 매우 효율적이지 않지만 glob 패턴이 필요한 경우 작동합니다 (/ var / www / *에서와 같이).

for f in $(cat 1.txt) ; do 
  rm "$f"
done

패턴이없고 파일의 경로에 공백이나 기타 이상한 요소가 포함되어 있지 않다고 확신하는 경우 다음과 같이 xargs를 사용할 수 있습니다.

xargs rm < 1.txt

4
경로에 공백이 포함 된 경우 첫 번째 솔루션 (CAT 사용)은 어떻게됩니까?
a.dibacco

58

파일 목록이 파일에 있다고 가정하고 1.txt다음을 수행하십시오.

xargs rm -r <1.txt

-r옵션은에 이름이 지정된 모든 디렉토리로 재귀를 발생시킵니다 1.txt.

파일이 읽기 전용 인 경우 -f옵션을 사용하여 강제로 삭제합니다.

xargs rm -rf <1.txt

프로그래밍 방식으로 삭제 하는 도구 에 대한 입력에주의하세요 . 확인 특정 입력 파일에 명명 된 파일이 정말 삭제되도록. 특히 단순 해 보이는 오타에주의하십시오. 예를 들어 파일과 접미사 사이에 공백을 입력하면 두 개의 개별 파일 이름으로 나타납니다.

file .txt

실제로 두 개의 별도의 파일입니다 : file.txt.

이것은 그렇게 위험 해 보이지 않을 수 있지만 오타가 다음과 같은 경우 :

myoldfiles *

대신로 시작하는 모든 파일을 삭제하는 그런 다음 myoldfiles, 당신은 삭제 될 겁니다 myoldfiles모든 현재 디렉토리가 아닌 점 파일 및 디렉토리. 아마도 당신이 원하는 것이 아닐 것입니다.


1
"myoldfiles /"또는 "/ tmp"는 -rf를 사용하면 훨씬 더 비참합니다. "/"옆의 공백 문자에 유의하십시오.
Ray

23

이것을 사용하십시오 :

while IFS= read -r file ; do rm -- "$file" ; done < delete.list

glob 확장이 필요한 경우 인용을 생략 할 수 있습니다 $file.

IFS=""
while read -r file ; do rm -- $file ; done < delete.list

그러나 파일 이름에는 "문제가있는"내용이 포함될 수 있으며 인용되지 않은 버전을 사용합니다. 파일에서이 패턴을 상상해보십시오.

*
*/*
*/*/*

이것은 현재 디렉토리에서 상당히 많이 삭제됩니다! glob 패턴이 더 이상 필요하지 않은 방식으로 삭제 목록을 준비한 다음 첫 번째 예제와 같이 인용사용하는 것이 좋습니다 .


3
이것은 현재 모든 /My Dir With Spaces/ /Spaces and globs/*.txt, 를 처리하는 유일한 답변이며 , --file-with-leading-dashes보너스로 POSIX이며 GNU / Linux, macOS 및 BSD에서 작동합니다.
그 다른 남자

17

개행 문자를 구분 기호로 정의하기 위해 '\ n'을 사용할 수 있습니다.

xargs -d '\n' rm < 1.txt

1.txt에 공백이있는 경로가 포함 된 경우 원하지 않는 항목을 삭제할 수 있으므로 -rf에주의하십시오. 그래서 새 줄 구분 기호가 더 안전합니다.

BSD 시스템에서는 -0 옵션을 사용하여 다음과 같은 구분 기호로 줄 바꾸기 문자를 사용할 수 있습니다.

xargs -0 rm < 1.txt

1
OS X에서 이것은 나를 얻는다xargs: illegal option -- d
waldyrious

좋은 지적. -0OS X 외에 다른 옵션이없는 것 같습니다.
Ray

2
xargs -I_ rm _OS X에서도 작동합니다. :) stackoverflow.com/a/39335402/266309
waldyrious

BSD xargs (가없는 경우)를 사용하는 경우 -d먼저 줄 바꿈을 null로 변환 할 수 있습니다.tr '\n' '\0' < 1.txt | xargs -0 rm
OrangeDog

13

이 한 줄짜리를 사용할 수 있습니다.

cat 1.txt | xargs echo rm | sh

쉘 확장을 수행하지만 rm최소 횟수를 실행 합니다.


확장이 너무 길지 않은 한?
Douglas Leeder

1
사실, glob은 너무 긴 인수 목록을 생성 할 수 있습니다. -n <n>인수를 추가하여 xargs각 rm에 전달되는 인수 수를 줄일 수 있지만 여전히 제한을 초과하는 단일 glob으로부터 보호하지는 못합니다.
tgdavies

13

xargs -I{} sh -c 'rm {}' < 1.txt당신이 원하는 것을해야합니다. 해당 파일에 잘못된 항목이 하나 있으면 많은 문제가 발생할 수 있으므로이 명령에주의하십시오.

이 답변은 @tdavies가 원본이 셸 확장을 수행하지 않았다고 지적한 후에 편집되었습니다.


감사합니다,하지만 삭제 폴더에 대한 필요가 없습니다, 파일 만
알렉산더

2
glob은 셸에서 '보이지'않기 때문에 확장되지 않습니다.
tgdavies

@tdavies 와우-당신 말이 맞아요. 이 명령 (조금 더 이상 하긴하지만)은 다음과 같이 작동합니다.xargs -I{} sh -c 'rm {}' < 1.txt
Mark Drago

4

이 특별한 경우에는 다른 답변에 언급 된 위험성으로 인해

  1. 예를 들어 Vim 및에서 편집 :%s/\s/\\\0/g하여 백 슬래시로 모든 공백 문자를 이스케이프하십시오.

  2. 그런 다음 :%s/^/rm -rf /명령 앞에옵니다. 함께 -r사용하면 파일이 안에 포함 된 다음에 나열 디렉토리를 가지고 걱정할 필요가 없습니다, 그리고 함께 -f그것으로 인해 누락 된 파일 또는 중복 된 항목에 불평하지 않습니다.

  3. 모든 명령을 실행하십시오. $ source 1.txt


공백은 이스케이프가 필요한 유일한 문자가 아니며, 파일 이름에서 널리 사용되는 것은 원치 않는 확장으로 이어질 수있는 모든 종류의 대괄호입니다.
emk2203

4

cat 1.txt | xargs rm -f | bash 명령을 실행하면 파일에 대해서만 다음이 수행됩니다.

cat 1.txt | xargs rm -rf | bash 명령을 실행하면 다음과 같은 재귀 동작이 수행됩니다.


2

다른 방법을 제공하기 위해 다음 명령을 사용할 수도 있습니다.

$ cat to_remove
/tmp/file1
/tmp/file2
/tmp/file3
$ rm $( cat to_remove )

1

다음은 또 다른 반복 예제입니다. 여기에는 항목이 '파일'(예 : '디렉토리')인지 확인하는 예로서 'if- 문'이 포함되어 있습니다.

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done

0

여기에서 폴더의 설정을 사용할 수 있습니다 deletelist.txt 동안 몇 가지 패턴을 피할 뿐만 아니라

foreach f (cat deletelist.txt)
    rm -rf ls | egrep -v "needthisfile|*.cpp|*.h"
end

0

이렇게하면 파일 이름에 공백이있을 수 있습니다 (재현 가능한 예).

# Select files of interest, here, only text files for ex.
find -type f -exec file {} \; > findresult.txt
grep ": ASCII text$" findresult.txt > textfiles.txt
# leave only the path to the file removing suffix and prefix
sed -i -e 's/:.*$//' textfiles.txt
sed -i -e 's/\.\///' textfiles.txt

#write a script that deletes the files in textfiles.txt
IFS_backup=$IFS
IFS=$(echo "\n\b")
for f in $(cat textfiles.txt); 
do 
rm "$f"; 
done
IFS=$IFS_backup

# save script as "some.sh" and run: sh some.sh

0

누군가 와일드 카드 확장없이 선호 sed하고 제거하는 경우 :

sed -e "s/^\(.*\)$/rm -f -- \'\1\'/" deletelist.txt | /bin/sh

알림 : 파일에서 절대 경로 이름을 사용하거나 올바른 디렉토리에 있는지 확인하십시오.

완전성을 위해 다음과 awk같습니다.

awk '{printf "rm -f -- '\''%s'\''\n",$1}' deletelist.txt | /bin/sh

작은 따옴표를 제거하면 와일드 카드 확장이 작동하지만 파일 이름에 공백이 포함 된 경우 위험합니다. 와일드 카드 주위에 따옴표를 추가해야합니다.

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