디렉토리에서 같은 크기의 파일을 삭제하는 방법은 무엇입니까?

디렉토리에서 같은 크기의 파일을 삭제하는 방법은 무엇입니까?

이미지가 있는데 같은 크기의 일부 파일을 삭제해야 합니다. 그러나 이러한 이미지를 모두 삭제하는 대신 대기열의 다음 이미지만 삭제합니다(알파벳순).

1.png    # 23,5 Kb
2.png    # 24,6 Kb
4.png    # 24,6 Kb > remove
8.png    # 24,6 Kb > remove
16.png   # 23,5 Kb

답변1

Linux를 사용 중이거나 GNU 도구에 액세스할 수 있는 경우 다음을 수행할 수 있습니다.

last=-1; find . -type f -name '*.png' -printf '%f\0' | sort -nz | 
    while read -d '' i; do 
        s=$(stat -c '%s' "$i"); 
        [[ $s = $last ]] && rm "$i"; 
    last=$s; 
done

설명하다

  • last=-1: 변수를 $last로 설정합니다 -1.
  • find . -type f -name '*.png' -printf '%f\0': 현재 디렉토리에서 이름이 .png다음으로 끝나는 모든 파일을 찾습니다.널 문자.
  • sort -gz\0: 구분된 입력 ( )을 숫자 ( )로 정렬합니다. 이렇게 하면 정렬된 파일 이름 목록이 생성됩니다.-z-n
  • while read -d '' i; do: 파일 이름 목록을 읽습니다. NULL로 구분된 데이터를 올바르게 처리하는 데 필요한 -d ''필드 구분 기호를 설정합니다.\0
  • s=$(stat -c '%s' "$i");:변수는 $s이제 현재 파일( )의 크기를 보유합니다 $i.
  • [[ $s = $last ]] && rm "$i";: 현재 파일의 크기가 이전 파일과 같을 경우 해당 파일을 삭제합니다.
  • last=$s: $last현재 파일의 크기를 설정합니다. 이제 다음 파일의 크기가 동일하면 이전 단계에서 해당 파일이 삭제됩니다.

답변2

POSIX구현에서는 크기별로 정렬된 목록을 제공하는 옵션을 ls지원합니다 -S(동일한 크기의 이름별로 정렬된 것으로 나타남). 이전 항목의 크기를 기억하고 "중복 항목"을 제거하여 목록을 쉘 루프로 파이프할 수 있습니다.

이것의 단점은 파일 이름을 얻는 것입니다(파일 이름에 공백이 있는 경우).

또는 유틸리티(예: Linux 또는 BSD)가 있는 플랫폼 중 하나를 사용하는 경우 stat이를 사용하여 크기와 파일 이름만으로 구성된 고정 형식 목록을 만든 다음 정렬할 수 있습니다.저것, 중복 크기를 확인하는 간단한(r) 스크립트에 전달합니다.

이 질문의 한 가지 복잡한 문제는 .GNU 및 BSD 유틸리티 핸들 의 옵션 이 16.png따르기 때문에 예제에서 "알파벳"을 의미하는 쉘 순서를 사용하지 않는다는 것입니다.8.png-gsort저것(근데 거기는 없어POSIX).

이러한 문제를 고려하면 sort스크립트는 정렬된 이름 목록(원하는 순서로)을 가져와 이를 사용하여 stat각 파일의 크기를 연속적으로 가져와야 합니다.

다음은 GNU를 사용하여 이를 보여주는 간단한 예입니다("rm"을 "echo"로 변경) stat.

#!/bin/sh
last=x
# the sed command strips a leading "./", which confuses "sort -g"
find . -name '*.png' |sed -e 's,^./,,' | sort -g | while true
do
    read item
    [ -z "$item" ] && break
    size=$(stat -c '%s' "$item")
    echo "$size>$item"
    if [ "x$size" = "x$last" ]
    then
        echo "rm -f \"$item\""
    fi
    last="$size"
done

관련 정보