it-swarm-ja.com

UNIXコマンドラインを介したファイルのグループからの小さなファイルのバッチ削除

写真でいっぱいのディレクトリがたくさん(400以上)あります。私がやりたいのは、これらの写真のサイズを大きくしておくことです。各ディレクトリには、31〜66個のファイルがあります。

各ディレクトリには、サムネイル、より大きなバージョン、およびexample.jpgというファイルがあります。

Example.jpgファイルを簡単にディスパッチしました:

rm */example.jpg

当初はサムネイルを削除するのは簡単だと思っていましたが、名前が一貫していないのが問題です。典型的なパターンはphoto1.jpgphoto1s.jpgでした。 rm */photo*s.jpgを実行しましたが、photoXs.jpgという名前のファイルのいくつかは実際には大きく、小さくはありませんでした。ああ。

だから私がしたいのは、ファイルサイズについて各ディレクトリをスキャンし、サムネイルを削除(または移動)することです。私は当初、すべてのファイルをls -Rし、各ファイルのサイズを抽出して、しきい値未満で保存すると思っていました。問題? 1つのディレクトリでは、ラージは1.1 MBで、サムは200kです。別のものでは、大きいものは200kで、小さいものは30kです。

さらに悪いことに、ファイルの名前は実際にはほとんどphoto1.jpgです。したがって、ファイルをすべて同じフォルダーに入れ、サイズで並べ替え、グループで削除するだけでは、名前を変更しないと機能しません。可能であれば、保持したいと思います。それらのフォルダにあります。

私はこれをすべて手動で行うことにほぼ決心しましたが、それから私はここで尋ねると思いました。

このタスクをどのように行いますか?

3
artlung

このスクリプトは、最小ファイルと最大ファイルのグループ間でサイズに大きなギャップがあることを前提としています。特に、大きいファイルの最小値は、小さいファイルの最大値の少なくとも2倍の大きさです。

スクリプト「imagedirstats」を呼び出して、次のようなループで実行します。

find /path/to/main/branch -type d | while read subdir; do (cd "$subdir" && ~/bin/imagedirstats ); done

ディレクトリツリー内の個々のディレクトリ内のファイルを検索して削除するため。

スクリプトは次のとおりです。

#!/bin/bash
# from http://superuser.com/questions/135951/batch-deletion-of-smaller-files-from-group-of-files-via-unix-command-line
# by Dennis Williamson - 2010-04-29

prevn=1     # prevent division by zero
factor=4    # how close to the largest of the small files to set the threshold, 4 == one fourth of the way above
min=1000    # ignore files below this size

while read n
do
    (( ratio = n / prevn ))
    if (( ratio > 1 && n > min ))
    then
        break
    fi
    if (( n > 0 ))
    then
        prevn=$n
    fi
done < <(find . -maxdepth 1 -name "*.jpg" -printf "%s\n" | sort -n)
# for OS X, comment out the preceding line and uncomment this one:
# done < <(find . -maxdepth 1 -name "*.jpg" | stat -f "%z" | sort -n)

# the following line would be the GNU equivalent using stat(1) instead of printf
# it's included here for reference:
# done < <(find . -maxdepth 1 -name "*.jpg" | stat -c "%s" | sort -n)

(( size = (n - prevn) / factor + prevn ))

echo "Smallest of the large: $n"
echo "Largest of the small: $prevn"
echo "Ratio: $ratio"
echo "Threshold: $size"

if (( ratio < 2 ))
then
    read -p "Warning: ratio too small. Delete anyway? Only 'Yes' will proceed" reply
    if [[ $reply != "Yes" ]]
    then
        echo "Cancelled" >&2
        exit 1
    fi
fi

# uncomment the delete on the following line to actually do the deletion

find . -maxdepth 1 -name "*.jpg" -size -${size}c # -delete

編集:警告プロンプトを移動して、有用な情報が最初に表示されるようにしました。欠落していたfiを修正しました。

編集2: 2つのfindコマンドの一貫性を保ちました。 OSX用にコメントアウトされたバリエーションを追加しました。スクリプトの実行に関する情報を追加しました。

あなたが見つけることができるいくつかの特定のカットオフがある場合、例えば、すべての大きな写真が200KBより大きい場合、あなたはこれを行うことができます:

find */*.jpg -size -200k -delete

最初にバックアップコピーを作成することをお勧めします。

4
Chris S

ファイルサイズに一貫性がない場合、画像のサイズは異なりますか?

ImageMagickに付属のツールであるidentifyを使用して、画像のサイズを取得できます。いくつかの簡単なbashスクリプトを使用して、サイズに応じて画像を操作できます。

identifyで画像の幅と高さを取得するには:

識別-フォーマット '%wx%h'ファイル名

次のような出力が得られます。

[john @ awesome:〜] $ identity -format '%wx%h' W4.JPG 
 1680x1050

次に、cutユーティリティを使用して、スクリプト内の数値を取得できます。

[john @ awesome:〜] $ identity -format '%wx%h' W4.JPG | cut -d'x '-f1 
 1680 
 [john @ awesome:〜] $ identity -format'%wx%h 'W4.JPG |カット-d'x'-f2 
 1050
3
John T

ファイル名に基づいてこれを実行する場合は、次のことを試してください。

find -name '*.jpg' | sed -ne 's:^\(.*\)\.jpg:\1s.jpg$:p' | xargs rm

すべての.jpgファイルを検索し、ファイル名の最後(「。」の直前)に「s」を付けて削除します。

0
petersohn