web-dev-qa-db-ja.com

サブフォルダー内の各ファイルに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 "$@"'

ただし、これはテストで1つのファイルのみを出力し、その前にすべてのファイルを出力します。私はこれらの2つが同じように実行されることを期待しますか?

4
Ali Caglayan

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

この優れた答え から引用するには:

シェル以外の他のプログラムがそれを使用できる必要がありますか?もしそうなら、それはスクリプトでなければなりません。

他の回答ですでに述べたように、関数をエクスポートすることでこれを回避することは可能かもしれませんが、確かにlotより簡単ですスクリプトを使用するだけです。

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

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

find tests -type f -exec fun {} +
2
Wildcard

この問題を解決するには、2つの方法があります。-n1を使用して一度に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 "$@"' --
1
Fedor Dikarev

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

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

find tests -type f -print0 | parallel -0 -Xj1 fun
1
Ole Tange