ディレクトリに多くのファイルがあり、その中に同じプレフィックスを持つファイルの1つだけを除いて、すべて削除したいと思います。たとえば、パターン付きのファイルがありますfilename.__<random_string>.pdf
。 (ファイル名は特定の長さの文字列にすることができます。)
foo.__.pdf
foo.__resume.pdf
foo.__name.pdf
bar.__.pdf
bar.__resume.pdf
bar.__name.pdf
今、同じプレフィックスを持つ3つのファイルのうちの1つだけが欲しいです。つまり、最初の3つのファイルのうちの1つと最後の3つのファイルのうちの1つだけが必要です。たとえば、ディレクトリには次のものを含める必要があります。
foo.__.pdf
bar.__.pdf
すべてのスクリプト言語またはシェルを使用した回答が許可されています。
ベストアンサー1
#!/bin/bash
declare -A seen
for name in *.__*.pdf; do
prefix=${name%%.__*.pdf}
if [[ -z ${seen[$prefix]} ]]; then
printf 'keeping "%s"\n' "$name"
seen[$prefix]=1
else
printf 'deleting "%s"\n' "$name"
# rm -f -- "$name"
fi
done
*.__*.pdf
上記のスクリプトは、ファイル名のワイルドカードパターンと一致する現在のディレクトリのすべてのファイル名からプレフィックスを抽出します。プレフィックスが以前に表示されなかった場合、ファイルは保持されます。それ以外の場合、ファイルは削除されます(rm
このコマンドは現在セキュリティ上の理由でコメントアウトされています)。
表示されたプレフィックスを追跡するために、プレフィックスという名前の連想配列にキーとして保存されますseen
。連想配列はbash
バージョン4で導入された。
*.__*.pdf
同じプレフィックスに一致するすべてのファイルは「同等」なので、すべてのファイルの名前を同じ名前に変更すると単一のファイルに短縮されます。
これは連想配列を必要とせず、以下を使用して簡単に実行できます/bin/sh
。
#!/bin/sh
for name in *.__*.pdf; do
prefix=${name%%.__*.pdf}
printf 'moving "%s" to "%s.__.pdf"\n' "$name" "$prefix"
# mv -f -- "$name" "$prefix.__.pdf"
done
ここで、プレフィックスを含むすべてのファイルはfoo
その名前に移動されますfoo.__.pdf
(mv
安全のためにコマンドはコメントアウトされます)。