이미지가 있는데 같은 크기의 일부 파일을 삭제해야 합니다. 그러나 이러한 이미지를 모두 삭제하는 대신 대기열의 다음 이미지만 삭제합니다(알파벳순).
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
-g
sort
저것(근데 거기는 없어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