1

ファイルを Web サーバーにアップロードするサードパーティ プログラムがあります。これらのファイルは画像であり、異なるフォルダーにあり、異なる名前が付いています。これらのファイルは、データベースへの参照を取得します。プログラムは新しい画像をインポートし、それらをそれらのフォルダーにアップロードします。既存のファイルがある場合は、名前を取得して特別なカウンターを追加し、データベースに新しい参照を作成すると、古い参照が削除されます。ただし、ファイルも削除する代わりに、コピーを保持します。

たとえば、画像ファイル名が「109101.jpg」であるとします。ファイルの新しいバージョンがあり、「109101_1.jpg」というファイル名でアップロードされます。これは、たとえば「109101_103.jpg」まで続きます。現在、このファイルより前の 103 個のファイルはすべて古く、削除される可能性があります。

プログラムは編集可能ではなく、サードパーティ製ではないため、その動作を変更することはできません。代わりに、これらのフォルダーを調べて、最新のイメージより前のすべてのイメージを削除するシェル スクリプトが必要です。したがって、「109101_103.jpg」のみが残り、この番号より前の他のすべては削除されます。また、副作用として、下線が 2 つ付いた名前の画像もあります (これらのみで、3 重のものはありません)。例: "109013_35_1.jpg" は元のもので、次は "109013_35_1_1.jpg" で、現在は "109013_35_1_24.jpg" になっています。というわけで、「109013_35_1_24.jpg」だけが生き残る必要があります。

今のところ、この問題を解決する方法もわかりません。何か案は?

4

2 に答える 2

1

これが1行のパイプラインです。私は悪ではないので、改行を挿入して表示されます。

for F in $(find . -iname '*.jpg' -exec basename {} .jpg \;
             | sed -r -e 's/^([^_]+|[^_]+_[^_]+_[^_]+)_[0-9]+$/\1/'
             | sort -u); do
    find -regex ".*${F}_[0-9]*.jpg" 
       | sort -t _ -k 2 -n | sort -n -t _ -k 4 -s | head -n -1;
done
于 2013-02-01T16:12:40.577 に答える
0

次のスクリプトは、特定のディレクトリ内のファイルを削除します。

#! /bin/bash
cd $1
shopt -s extglob                                       # Turn on extended patterns.
shopt -s nullglob                                      # Non matched pattern expands to null.
delete=()
for file in               +([^_])_+([0-9]).jpg \
        +([^_])_+([0-9])_+([0-9])_+([0-9]).jpg ; do    # Only loop over non original files.
    [[ $file ]] || continue                            # No files in the directory.
    base=${file%_*}                                    # Delete everything after the last _.
    num=${file##*_}                                    # Delete everything before the last _.
    num=${num%.jpg}                                    # Delete the extension.
    [[ -f $base.jpg ]] && rm $base.jpg                 # Delete the original file.
    [[ -f "$base"_$((num+1)).jpg ]] && delete+=($file) # The file itself is scheduled for deletion.
done
(( ${#delete[@]} )) && rm "${delete[@]}"

番号付きのファイルは、別のファイルの「次の」ファイルが削除される可能性があるため、すぐには削除されません。それらは配列に記憶され、最後に削除されます。

スクリプトを再帰的に適用するには、次を実行できます

find /top/directory -type d -exec script.sh {} \;
于 2013-02-01T11:24:05.373 に答える