サブフォルダ内の各ファイルに bash 機能を繰り返し適用する

サブフォルダ内の各ファイルに bash 機能を繰り返し適用する

ディレクトリ内の各ファイルに bash 関数を繰り返し適用するスクリプトを作成しようとしています。たとえば、そのディレクトリにtestsファイルとサブディレクトリの両方が含まれている場合、スクリプトは

find tests -type f -print0 | xargs -0 echo

完璧に動作します。これで、エコーの代わりにbash機能を適用できるようにしたいので、次のようなことを考えました。

function fun() {
    echo $1
}

export -f fun

find tests -type f -print0 | xargs -0 bash -c 'fun "$@"'

しかし、以前はすべてのファイルを出力しましたが、テストでは単一のファイルのみを出力しました。私はこれら2つを同じように実行したいと思います。そうですか?

答え1

シェルスクリプトを使用します。

から引用この素晴らしい答え:

シェルに加えて、他のプログラムでそれを使用できる必要がありますか?その場合はスクリプトでなければなりません。

他の答えですでに指摘したように、可能関数をエクスポートしてこの問題を解決してください。しかし、これは確かにたくさんスクリプトを使用する方が簡単です。

#!/bin/bash
# I'm a script named "fun"!  :)
printf '%s\n' "$@"

その後、funスクリプトをPATH(おそらく~/bin)のどこかに置き、実行可能であることを確認してから、次のように実行できます。

find tests -type f -exec fun {} +

答え2

-n1この問題を解決する方法は2つあります。すべての引数を使用するか、ループ関数内で一度に1つの引数のみを使用してコマンドを実行するようにxargsに指示できますfun

function fun() { echo $1 }
export -f fun
find tests -type f -print0 | xargs -n1 -0 bash -c 'fun "$@"' --

または

function fun() { while [ -n "$1" ]; do echo $1; shift; done }
export -f fun
find tests -type f -print0 | xargs -0 bash -c 'fun "$@"' --

答え3

GNU Parallelを使用すると、次のようになります。

function fun() {
    echo "$@"
}
export -f fun

find tests -type f -print0 | parallel -0 -Xj1 fun

関連情報