1

すべてのサブディレクトリに対して何かを実行したい場合は、次のいずれかを実行する必要があることを何度も読みました。

find . -name '*' -exec command arguments {} \;

find . -type f -print0 | xargs -0 command arguments

find . -type f | xargs -I {} command arguments {} arguments

問題は、コア関数ではうまく機能しますが、コマンドがユーザー定義関数またはスクリプトの場合は期待どおりに機能しないことです。修正方法は?

したがって、私が探しているのは、 or を置き換えることができるコード行またはスクリプトでありcommandmyfunction現在myscript.shのディレクトリからすべてのサブディレクトリに移動し、指定した引数を使用してそのような関数またはスクリプトを実行します。

別の言い方をすれば、現在のディレクトリだけでなく、すべてのサブディレクトリでも機能するようにしたいと考えていfor file in *; do command_myfunction_or_script.sh arguments $file; doneます。

4

4 に答える 4

2

の代わりに-exec、を試してください-execdir

場合によっては、以下を使用する必要があるかもしれませんbash

foo () { echo $1; }
export -f foo
find . -type f -name '*.txt' -exec bash -c 'foo arg arg' \;

最後の行は次のようになります。

find . -type f -name '*.txt' -exec bash -c 'foo "$@"' _ arg arg \;

どの引数をいつ拡張する必要があるかによって異なります。アンダースコアはを表し$0ます。

-execdir必要に応じて、私が持っている場所で使用できます-exec

于 2012-06-11T16:34:36.257 に答える
1

関数で find を使用する方法はいくつかあるかもしれませんが、それほどエレガントではありません。bash 4 を使用している場合、おそらくやりたいことは globstar を使用することです。

shopt -s globstar
for file in **/*; do
    myfunction "$file"
done

POSIX または古いバージョンの bash との互換性を探している場合は、bash を呼び出すときに、関数を定義するファイルをソースにする必要があります。だから、このようなもの:

find <args> -exec bash -c '. funcfile;
    for file; do
        myfunction "$file"
    done' _ {} +

しかし、それはただ醜いです。この時点に到達すると、通常は自分の関数を自分のスクリプトに入れ、それでPATH生活します。

于 2012-06-11T15:48:31.313 に答える
1

あなたが与える例は、次のとおりです。

find . -name '*' -exec command arguments {} \;

現在のディレクトリからすべてのサブディレクトリに移動してcommandそこで実行するのではなくcommand、現在のディレクトリから、find によってリストされた各ファイルへのパスを引数として実行します。

実際にディレクトリを変更してスクリプトを実行したい場合は、次のようなことを試すことができます。

STDIR=$PWD; IFS=$'\n'; for dir in $(find . -type d); do cd $dir; /path/to/command; cd $STDIR; done; unset IFS

ここでは、現在のディレクトリが保存されSTDIR、bash の内部フィールド セパレーターが改行に設定されているため、名前がスペースで分割されません。次に、返された各ディレクトリ ( -type d) に対して、そのディレクトリに移動してコマンドを実行し (ディレクトリを変更すると相対パスが壊れるため、ここではフル パスを使用します)、cd で開始ディレクトリに戻ります。findcd

于 2012-06-11T16:04:58.053 に答える
1

bash 関数を使用する場合は、これが 1 つの方法です。

work ()
{
  local file="$1"
  local dir=$(dirname $file)
  pushd "$dir"
    echo "in directory $(pwd) working with file $(basename $file)"
  popd
}
find . -name '*' | while read line;
do
   work "$line"
done
于 2012-06-11T17:45:33.947 に答える