ディレクトリから同じサイズのファイルを削除する方法は?

ディレクトリから同じサイズのファイルを削除する方法は?

画像があるため、同じサイズの一部のファイルを削除する必要があります。ただし、これらのイメージをすべて削除するのではなく、キューの次のイメージのみを削除します(アルファベット順)。

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など)を含むプラットフォームの1つを使用している場合は、statそれを使用してサイズとファイル名のみで構成される固定形式のリストを作成してソートできます。それ、重複サイズを確認する単純な(r)スクリプトに渡します。

この質問の複雑な問題の1つは、.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

関連情報