find コマンドの -exec オプションにある個々のファイル名とパス

find コマンドの -exec オプションにある個々のファイル名とパス

脱出して評価を表現する作業をしています。ファイルで動作し、標準出力に出力される...構造find内でコマンドを実行しようとしています。コマンドラインで正常に使用するには、次のように新しいファイルにリダイレクトするだけです。-exec COMMANDCOMMANDCOMMAND

COMMAND inputfilename.md > outputfilename.md.conf

これは素晴らしい作品です。しかし、再帰的に繰り返したい場合みんなを使用してディレクトリとサブディレクトリ内のファイルをfind -exec正しくリダイレ​​クトできるように、ファイル名とパスを区切る方法がわからないようです。たとえば、これを行うとエラーが発生します。

find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;

{}フルファイルパスが拡張されるためです。私はbasenameさまざまな組み合わせを試しましたが、dirname評価できないようです(代わりに「basename」などの文字列のみを取得します)。たとえば、「basename」というテキストが表示されたため、機能しません。

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'

どんな助けでも大変感謝します。全体として、目標は次のとおりです。

  1. *.mdディレクトリ内の一致するすべてのファイルを繰り返し繰り返します。
  2. 繰り返しごとに同じ文字列が実行されますCOMMAND inputfile.md > ~/newdirectory/inputfile.md.confinputfile

ありがとうございます!

答え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' _ {} +

関連情報