find を使用して複数のファイルに対してスクリプトを実行するにはどうすればよいでしょうか?

find を使用して複数のファイルに対してスクリプトを実行するにはどうすればよいでしょうか?

つまり、基本的にはたくさんの.csvファイルを見つけて、それらすべてに書いたスクリプトを使用する必要があります。

find . -type f -name "*.csv" | xargs ./extractdata

これは機能しますが、必要なファイルがすべてではなく、1 つのファイルのみを実行します。助けてください。

答え1

動作しない理由は、xargsコマンド ラインにできるだけ多くのファイルを詰め込むためです。

したがって、「extractdata」スクリプトは一度にすべてのファイルを受け取り、おそらく最初の引数のみを処理します。つまり、N個のファイルがある場合、次のように実行します。1つスクリプト全てファイルを引数として指定します。

次の引数を使用する必要があります-n:

... | xargs -n 1 ./extractdata

この方法ではN個のファイルがあり、N個のスクリプトを実行します。1つファイル引数それぞれ。

findただし、これは オプションを指定して実行する場合とほぼ同じです(違いの 1 つは、見つかった順にファイルを処理するのに対し、パイプの場合は、たとえば、 および/または-execを渡した後にそれを実行できることです)。sortgrep

find ... -exec /path/to/extractdata \{\} \;

スクリプトを並列実行することもできますparallel。これは一度に4つのインスタンスを実行します。おそらくデータ、RAM、ハードウェアに応じて、より効率的な処理が可能になります。

... | parallel -n 1 -j 4 ./extractdata

(「extractdata」が固定名を持つ一時ファイルを使用する場合 (これは良い方法ではありません)、2 つ以上のスクリプトが並行して実行されると、互いの一時ファイルに書き込みが行われ、混乱が生じます)。

答え2

もう 1 つのオプションは次のfdツールです:

fd csv -x ./extractdata

https://github.com/sharkdp/fd

答え3

これを解決するには多くの方法があります。たとえば、find次のようにスクリプトを呼び出すように要求できます。

 $ find . -type f -name "*.csv" -exec your_script {} ;

{} は、毎回見つかったファイル名です。

これらの文字をエスケープする必要があるかもしれません:

 $ find . -type f -name "*.csv" -exec your_script \{\} \;

関連情報