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 {} +
上記の解決策との違いは、-execdir
1つ(またはごくわずか)のスクリプトのみが実行され、より速い代替項目で置き換えられるため、以前の変形よりも潜在的に高速になることです。 sh -c
dirname
この答えの2つのバリエーションに関連しています。