이름이 중복되지 않은 모든 파일을 삭제하시겠습니까?

이름이 중복되지 않은 모든 파일을 삭제하시겠습니까?

다음 내용을 포함하는 큰 파일 목록이 제공됩니다.

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

관련 정보