명령줄에서 여러 하위 폴더에 있는 동일한 이름의 파일을 삭제하는 방법은 무엇입니까?

명령줄에서 여러 하위 폴더에 있는 동일한 이름의 파일을 삭제하는 방법은 무엇입니까?

101개의 하위 폴더가 포함된 폴더가 있습니다 simulations. 이러한 하위 폴더의 posterior_predictive_sim_1이름은 입니다 posterior_predictive_sim_101.

각 하위 폴더에는 , , seq.nexseq[1].nex5 개의 파일이 포함되어 있습니다 .seq[2].nexseq[3].nexseq[4].nex

각 하위 폴더에서 seq[1].nex, seq[2].nex, seq[3].nex및 파일을 삭제하고 싶습니다 .seq[4].nexseq.nex

명령줄에서 이 작업을 어떻게 수행합니까?

답변1

단지 rm:

rm simulations/posterior_predictive_sim_*/seq\[[1-4]\].nex

이스케이프된 \[\]문자 그대로의 대괄호입니다. 이스케이프되지 않은 콘텐츠는 [1-4]숫자 1~4와 일치하는 glob 패턴입니다.

이는 전역 확장 파일 이름 수가 하나의 명령줄에 들어갈 수 있는 수를 초과하지 않는 경우에만 작동합니다.ARG_MAX제한 - 운영 체제에 따라 다르지만 최신 Linux에서는 약 2백만 자입니다. ARG_MAX는 와 같은 외부 명령에 적용되지만 또는 와 rm같은 셸 내장 명령에는 적용되지 않습니다 .forecho

또한, 먼저 테스트를 하시기 /bin/echo보다는 사용해 보시기 바랍니다 rm. 이유: 1. /bin/echo는 안전하며 아무것도 삭제하지 않습니다. 2. /bin/echo쉘에 내장된 echo 버전이 아닌 외부 명령이므로 총 명령 길이가 <= ARG_MAX인지도 테스트합니다.

GNU 사용 find:

find simulations/ -type f -name 'seq\[[1-4]\].nex' -delete

-ls또는 으로 실행하는 것이 좋습니다 .-print 앞으로원하는 대로 작동하는지 확인하려면 다음과 같이 -delete실행 하세요 .-exec rm

또는:

find simulations/ -type f -name 'seq\[[1-4]\].nex' -exec rm {} +

+find의 일부 고대 버전은 술어의 끝을 지원하지 않으므로 -exec대신 다음을 사용하십시오 \;.

find simulations/ -type f -name 'seq\[[1-4]\].nex' -exec rm {} \;

+와 차이점은 find 를 사용할 때 가능한 한 많은 파일 이름 인수를 명령에 \;넣으려고 한다는 것입니다 (다시 ARG_MAX). 를 사용하면 파일 이름당 한 번 실행 됩니다 . 이는 분명히+rm\;rm많은속도는 느리지만 여전히 유용합니다(예를 들어 파일 이름 인수만 사용하는 프로그램을 실행해야 하는 경우).

그건 그렇고, \;그것은 특별한 것이 아닙니다 find. 실제로 그 자체는 터미네이터 find역할만 합니다 . 이는 쉘이 세미콜론을 전달하는지 확인하기 위한 것입니다 . 즉, 쉘이 이를 명령문의 끝으로 해석하는 것을 방지하기 위한 것입니다 . 쉘 문은 줄 바꿈이나 세미콜론으로 구분됩니다.;-exec\find;find

답변2

먼저 파일 목록이 필요합니다. ls, find, ...를 사용하여 fd텍스트 파일로 저장할 수 있습니다 . ls posterior_predictive_sim_*/ > all.txt사람들은 ls 구문 분석에 대해 불평합니다. tl;dr은 여기서 중요하지 않습니다.

그런 다음 실제로 삭제하려는 파일을 필터링하고 싶습니다. ( cat all.txt | grep -v 'seq.nex' > del.txt쉘이 보다 보수적인 정규식 패턴을 허용하도록 만들 수도 있습니다 seq[\d+]\.nex).

이제 열어서 del.txt정말로 모든 것을 삭제하고 싶은지 확인하세요. 필요한 경우 파일을 수동으로 편집할 수 있습니다.

마지막으로 실제로 삭제하십시오. rm한 번에 여러 개의 파일 이름을 얻을 수 있으므로 수천 개의 파일이 없으면 이 방법을 시도해 볼 수 있습니다. 저는 GNU Parallel: 을 사용하는 것을 좋아합니다 cat del.txt | parallel --dry-run rm {}. 실행하려는 실제 명령을 인쇄하고 --dry-run실제로 실행하려면 제거합니다.

가장자리에 살고 싶다면 파일에 저장하는 대신 이러한 명령을 모두 서로 파이프할 수도 있습니다. 실수로 rm파일을 복구할 수 없기를 바랍니다. 그런데 사용https://github.com/andreafrancia/trash-cli대신 파일 삭제를 취소할 수 있습니다.

답변3

루프를 사용하십시오.

for i in $(ls); do rm posterior_predictive_sim_$i/seq\[*.nex; done


나 자신과 다른 사람들에게 왜 안되는지 상기시키기 위해 이것을 남겨 둡니다. 아래 CAS의 의견을 참조하십시오.

관련 정보