특정 패턴이 포함된 파일이 있는 디렉터리에서 파일을 제거합니다.

특정 패턴이 포함된 파일이 있는 디렉터리에서 파일을 제거합니다.

무작위로 이름이 지정된 100개의 텍스트 파일이 포함된 "/home/ben/files"라는 디렉터리가 있다고 가정해 보겠습니다. 100개의 텍스트 파일 중 일부에는 "DELETEME"이라는 단어만 포함되어 있습니다.

예를 들어 file1.txt, file2.txt, file3.txt, file4.txt, file5.txt... 등입니다.

이 패턴이 포함된 파일을 어떻게 삭제해야 합니까?

답변1

최소한 GNU grep을 사용하면 다음을 시도해 볼 수 있습니다.

grep -lZr "DELETEME" /home/ben/files | xargs -0 rm

경고: 이 작업은 /home/ben/files하위 폴더를 통해 반복됩니다. 이를 원하지 않으면 더 많은 예방 조치를 취해야 합니다.

(빈 구분 기호 사용을 제안한 댓글의 Cas에게 감사드립니다.)

답변2

GNU 사용 find:

먼저 몇 가지 설정을 수행하고 디렉터리를 만들고 그 안에 100개의 빈 파일을 만든 다음 그 중 일부에 "DELETEME"을 추가합니다.

mkdir files
touch files/{001..100}
for i in 001 010 020 030 040 050 065 077 088 099 ; do echo "DELETEME" >> files/$i ; done

다음으로 DELETEME이 포함된 파일을 나열합니다.

find ./files/ -type f -exec grep -q DELETEME {} \; -print
./files/050
./files/001
./files/065
./files/020
./files/040
./files/030
./files/088
./files/077
./files/099
./files/010

그러면 true 를 반환하는 모든 파일이 인쇄됩니다 grep -q DELETEME. 여기서 \;끝나는 것이 중요합니다 .-exec아니요 +), 각 파일을 개별적으로 테스트해야 하기 때문입니다. 그렇지 않으면 종료 코드가 grep -q현재 실행 중인 전체 파일 배치에 대한 것입니다.

find의 조건자는 기본적으로 AND 연산으로 함께 연결되므로 그 효과를 대략적으로 영어로 번역하면 "grep AND는 -exec이전 항목이 true를 반환한 모든 파일을 삭제합니다"입니다.

이는 쉘 메타 문자, 개행 및 기타 공백을 포함하여 유효한 문자가 포함된 파일 이름에 적용됩니다.

마지막으로 일치 항목을 제거하려면 -delete대신 다음을 사용하세요 -print.

find ./files/ -type f -exec grep -q DELETEME {} \; -delete

사용 중인 버전에 find가 없으면 다시 사용할 -delete수 있습니다 .-exec

find ./files/ -type f -exec grep -q DELETEME {} \; -exec rm {} +

파일 이름을 개별적으로 삭제할 필요가 없으므로 여기서 +두 번째 것을 사용할 수 있습니다. 일괄 삭제하는 것이 더 좋고 빠릅니다.-exec

물론, -maxdepth 1재귀를 방지하기 위해 find의 다른 술어를 사용할 수 있습니다.


그런데 다음이 포함된 파일을 삭제하려면오직"DELETEME", 그게 다입니다. 다음을 수행해야 합니다.

먼저 그러한 파일이 하나 이상 있는지 확인하십시오.

$ echo "DON'T DELETEME" > files/001

DELETEME 및 기타 내용이 포함된 파일 목록을 인쇄합니다.

$ find ./files/ -type f -exec grep -q '^DELETEME$' {} \; -exec grep -vq '^DELETEME$' {} \; -print
./files/001

이 경우에는 그냥 정규식을 사용하는 ^DELETEME$것이 아니라 DELETEMEDELETEME이 포함된 줄만 일치시키고 줄에 다른 항목은 아무것도 일치시키지 않기를 원하기 때문입니다. 행에서 선택적 선행 및/또는 후행 공백을 허용하려면 다음을 사용하십시오.^[[:space:]]*DELETEME[[:space:]]*$

그런 다음 이를 -exec grepDivide가 포함된 다른 일치 항목 과 결합합니다 ^DELETEME$.

!이제 두 번째 파일을 무효화하기 위해 (boolean NOT)을 사용하여 DELETEME이 포함된 파일(다른 콘텐츠가 포함된 파일과 함께)을 계속 나열할 수 있습니다 -exec.

$ find ./files/ -type f -exec grep -q '^DELETEME$' {} \; ! -exec grep -vq '^DELETEME$' {} \; -print
./files/050
./files/065
./files/020
./files/040
./files/030
./files/088
./files/077
./files/099
./files/010

./files/001우리가 원하는 파일이 목록에서 누락되었습니다.

또한 !두 번째 술어 앞에 오는 내용에 유의하십시오 -exec. 이것은 매우 중요하고 간과하기 쉬우므로 분명히 했습니다.

이 예에서는 먼저 -exec grep포함된 파일 목록을 가져온 ^DELETEME$다음 ^DELETEME$을 제외한 모든 파일을 포함하는 파일을 AND로 연산하지 않습니다.

파일을 -print대체하거나 -delete실제로 삭제할 수 있습니다 .-exec rm {} +


추신: 이보다 더 복잡한 경우에는 아마도 다음을 사용하여 Perl 스크립트를 작성하는 경향이 있습니다.파일::찾기기준 치수.

어떤 것들은 그냥많은부울 연산자에 연결된 조건자 체인이 있는 매우 긴 명령줄을 사용하는 것보다 절차적 언어 스타일로 작성하는 것이 더 쉽습니다 find(논리 체인을 잃기 쉽습니다).

관련 정보