무작위로 이름이 지정된 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$
것이 아니라 DELETEME
DELETEME이 포함된 줄만 일치시키고 줄에 다른 항목은 아무것도 일치시키지 않기를 원하기 때문입니다. 행에서 선택적 선행 및/또는 후행 공백을 허용하려면 다음을 사용하십시오.^[[:space:]]*DELETEME[[:space:]]*$
그런 다음 이를 -exec grep
Divide가 포함된 다른 일치 항목 과 결합합니다 ^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
(논리 체인을 잃기 쉽습니다).