find
エスケープと式の評価に苦労しています。 ...構造内でコマンドを実行しようとしています。この-exec COMMAND
構造では、COMMAND
1 つのファイルに対して操作が行われ、stdout に出力されます。これをCOMMAND
コマンド ラインで通常どおり使用するには、次のように新しいファイルにリダイレクトするだけです。
COMMAND inputfilename.md > outputfilename.md.conf
これはうまく動作します。しかし、再帰的にループしたい場合は全てディレクトリとそのサブディレクトリ内のファイルを でリダイレクトする場合find -exec
、ファイル名とパスを分離して適切にリダイレクトする方法がわかりません。たとえば、次のコードではエラーが発生します。
find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;
はファイルパス全体を拡張します。と{}
のさまざまな組み合わせを試しましたが、評価できないようです(代わりに、文字列「basename」などが表示されます)。たとえば、これは機能しませんでした。テキスト「basename」はbasename
dirname
find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/''basename {}''.conf' \;
(このエラーが返されます: 'No such file or directory - .//newdirectory/README.md.conf > ~/wiki/newdirectory/basename .//newdirectory/README.md.conf'
)。
ご協力いただければ幸いです。要約すると、目的は次のとおりです。
*.md
ディレクトリ内の一致するすべてのファイルを再帰的に反復処理する- 各反復で同じ文字列である
COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf
ところを実行します。inputfile
ありがとう!
答え1
何をするにしても、シェルを呼び出して、結果に応じて場所が決まるファイルにコマンド出力をリダイレクトする必要がありますfind
。
find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND "$0" > ~/wiki/newdirectory/"${0##*/}.cong"' {} \;
{}
シェル スクリプト内では置換しないでください。これはすべてのシステムでサポートされているわけではありません。サポートされている場合でも、ファイル名をシェル構文の一部として扱うため、通常は機能しません。たとえば、 というファイルが;rm -rf ~;.md
あると、すべてのファイルが消去されます。
${0##*/}
純粋な文字列操作を使用して、ファイルのベース名を取得します。 を使用することもできます$(basename -- "$0")
。
答え2
find
承認されれば-execdir
、これは機能するはずです
find . -name '*.md' -not -path './/.git/*' -execdir COMMAND {} > ~/wiki/newdirectory/{}.cong \;
交互に
find . -name '*.md' -not -path './/.git/*' -exec bash -c \
'for f; do COMMAND "$f" > ~/wiki/newdirectory/"${f##*/}".cong; done' _ {} +