指定されたワイルドカードパターンと一致するファイルを除いて、ディレクトリ内のすべてのファイルを削除します。

指定されたワイルドカードパターンと一致するファイルを除いて、ディレクトリ内のすべてのファイルを削除します。

ディレクトリに多くのファイルがあり、その中に同じプレフィックスを持つファイルの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.__.pdfmv安全のためにコマンドはコメントアウトされます)。

おすすめ記事