다음 내용을 포함하는 큰 파일 목록이 제공됩니다.
FILE1.doc
FILE1.pdf
FILE2.doc
FILE3.doc
FILE3.pdf
FILE4.doc
목록에서 이름이 중복되지 않은 모든 파일을 삭제할 수 있는 터미널 명령이 있습니까? 이 경우...FILE2.doc 및 FILE4.doc?
답변1
Bash를 사용하면 이름은 같지만 확장자가 다른 파일이 없는 모든 파일이 삭제됩니다.
for f in *; do same=("${f%.*}".*); [ "${#same[@]}" -eq 1 ] && rm "$f"; done
이 방법은 이름에 공백이 있는 경우에도 모든 파일 이름에 안전합니다.
어떻게 작동하나요?
for f in *; do
그러면 현재 디렉터리의 모든 파일에 대한 루프가 시작됩니다.
same=("${f%.*}".*)
그러면 동일한 기본 이름을 가진 모든 파일의 이름을 포함하는 bash 배열이 생성됩니다.
$f
우리 파일의 이름입니다.${f%.*}
확장자가 없는 파일 이름입니다. 예를 들어, 파일이 이면FILE1.doc
파일${f%.*}
은 입니다FILE1
."${f%.*}".*
기본 이름은 동일하지만 확장자는 모두 파일입니다.("${f%.*}".*)
이 이름의 bash 배열입니다.same=("${f%.*}".*)
변수에 배열을 할당합니다same
.[ "${#same[@]}" -eq 1 ] && rm "$f"
해당 기본 이름을 가진 파일이 하나만 있으면 삭제합니다.
"${#same[@]}"
배열의 파일 수입니다same
.[ "${#same[@]}" -eq 1 ]
해당 파일이 하나만 있는 경우 참입니다.&&
논리 AND입니다.rm "$f"
이전 문이 논리적인 true를 반환하는 경우에만 다음 문을 실행합니다.done
이것은 주기의 끝을 표시합니다
for
.
답변2
파일 목록이 어떤 파일에 있다고 가정 /tmp/files.list
하면 다음과 같습니다 ls * > /tmp/files.list
.
그러면 sort -u /tmp/files.list
중복되지 않은 정렬된 파일 목록이 제공됩니다(위의 작업을 수행한 경우에는 필요하지 않음 ls * > /tmp/files.list
). 당신은 일부와 함께 그것을 처리할 수 있습니다awk
스크립트는 다음에서 영감을 얻었습니다.이것,예를 들어
sort -u /tmp/files.list | awk '{
function basename(file) {
sub(".*/", "", file)
return file
}
curfil=$0;
if (basename(curfil)==basename(prevfil)) system("rm " + curfil);
prevfil=curfil;
}'
아직 테스트해본 적은 없으니 참고해주세요.
답변3
겉으로는 단순해 보이지만 복잡한 또 다른 접근 방식은 다음과 같습니다.
for x in `for i in *; do echo $i ; done | cut -d'.' -f1 | uniq -u `; do rm $x.*; done