Find -execを使用してgrepの内容を使用してファイルの名前を変更します。

Find -execを使用してgrepの内容を使用してファイルの名前を変更します。

findを使用してファイルのリストを取得し、pdfgrepを使用してファイルから文字列を取得し、その文字列を使用してファイルの名前を変更しようとします。

分解コマンドは次のとおりです。

find . -name "*PayrollSelfBill_42652301*" -exec pdfgrep {}  -o -e "42652301-.{10}"

findは私が興味のあるファイルを取得し、-exec部分のpdfgrepは正しい文字列を抽出します。

{}に保存されているファイルをpdfgrepの出力に変換したいです。

変数($()/backticksを使用)と複数の-execsを作成しましたが、何も機能しないようです。

誰もがエレガントな解決策を持っていますか?

ベストアンサー1

単一のファイルの場合、$filename私が正しく理解した場合は、次のようなことをしたいと思います。

mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"

...$filename現在のディレクトリのファイル名とみなされます。正しいですか?そうでなければ、以下のコードも間違っています。

findいいですね。以下を接続してみましょう-execdir

find . -type f -name "*PayrollSelfBill_42652301*" -execdir sh -c '
    filename=$1
    mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"' sh {} ';'

これにより、関心のあるファイルを見つけてスクリプトスニペットが実行されます。ファイルが見つかったディレクトリと同じディレクトリ(これが-execdirとの違いです-exec。)

可能

find . -type f -name "*PayrollSelfBill_42652301*" \
    -execdir mv -i {} "$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

実際にサブシェルを追加せずに動作します...今考えてみましょう。しかし、私は-execdirこれがあるので、サブシェルを呼び出す方が安全であると思いますfind


$pathname見つかったファイルの1つだとしますが、いいえ現在のディレクトリでは、以下はファイルに対して同じことを行います。

mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"

ここで${pathname%/*}見つかったファイルのディレクトリに展開します(と同じ$( dirname "$pathname" ))。

これはうまくいくかもしれません

find . -type f -name "*PayrollSelfBill_42652301*" \
    -exec  mv -i {} "$( dirname {} )/$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

ただし、より効率的にこれを使用して複数の-exec ... {} +ファイルをバッチ処理できます。

find . -type f -name "*PayrollSelfBill_42652301*" -exec sh -c '
    for pathname do
        mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"
    done' sh {} +

上記の解決策との違いは、-execdir1つ(またはごくわずか)のスクリプトのみが実行され、より速い代替項目で置き換えられるため、以前の変形よりも潜在的に高速になることです。 sh -cdirname

この答えの2つのバリエーションに関連しています。

おすすめ記事