230

findシェルで定義した関数を実行する方法はありますか?

例えば:

dosomething () {
  echo "Doing something with $1"
}
find . -exec dosomething {} \;

その結果は次のとおりです。

find: dosomething: No such file or directory

見る方法はありますかfind-execdosomething

4

15 に答える 15

296

シェル関数の実行方法を知っているのはシェルだけなので、関数を実行するにはシェルを実行する必要があります。また、エクスポート用に関数を でマークする必要がありますexport -f。そうしないと、サブシェルはそれらを継承しません。

export -f dosomething
find . -exec bash -c 'dosomething "$0"' {} \;
于 2010-12-01T05:38:05.060 に答える
142
find . | while read file; do dosomething "$file"; done
于 2011-12-13T12:39:32.013 に答える
34

Jac の答えは素晴らしいですが、簡単に克服できる落とし穴がいくつかあります。

find . -print0 | while IFS= read -r -d '' file; do dosomething "$file"; done

これは区切り文字として改行の代わりに null を使用するため、改行を含むファイル名が機能します。また、バックスラッシュのエスケープを無効にするフラグも使用し-rます。これがないと、ファイル名のバックスラッシュは機能しません。またIFS、名前の潜在的な末尾の空白が破棄されないようにクリアします。

于 2014-10-13T21:42:55.923 に答える
22

{}以下に示すように引用符を追加します。

export -f dosomething
find . -exec bash -c 'dosomething "{}"' \;

findこれにより、名前に括弧が含まれるファイルなど、によって返される特殊文字によるエラーが修正されます。

于 2011-12-16T02:25:52.177 に答える
15

結果の一括処理

効率を上げるためxargsに結果をまとめて処理する人が多いですが、非常に危険です。findそのため、結果を一括で実行する別の方法が に導入されました。

ただし、この方法には、コマンドの最後にあるPOSIX の要件など、いくつかの警告が伴う場合があることに注意findしてください。{}

export -f dosomething
find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +

findは多くの結果を引数として の 1 回の呼び出しに渡しbashfor-loop はそれらの引数を繰り返し処理し、それらのdosomethingそれぞれに対して関数を実行します。

上記の解決策では、 で引数が開始されます。これが(を表す)$1がある理由です。_$0

結果を1つずつ処理する

同様に、受け入れられた上位の回答は次のように修正する必要があると思います

export -f dosomething
find . -exec bash -c 'dosomething "$1"' _ {} \;

引数は常に で始まる必要があるため、これはより正気であるだけでなく、によって返されるファイル名がシェルにとって特別な意味を持つ場合、 $1using$0によって予期しない動作が発生する可能性があります。find

于 2016-11-08T18:22:50.000 に答える
9

スクリプト自体を呼び出し、見つかった各項目を引数として渡します。

#!/bin/bash

if [ ! $1 == "" ] ; then
   echo "doing something with $1"
   exit 0
fi

find . -exec $0 {} \;

exit 0

スクリプトを単独で実行すると、探しているものが見つかり、各検索結果を引数として渡して自分自身を呼び出します。スクリプトが引数付きで実行されると、引数でコマンドを実行してから終了します。

于 2014-08-22T18:10:38.973 に答える
3

そのように関数を実行することはできません。

これを克服するには、関数をシェル スクリプトに配置し、それを呼び出すことができます。find

# dosomething.sh
dosomething () {
  echo "doing something with $1"
}
dosomething $1

これを find で次のように使用します。

find . -exec dosomething.sh {} \;
于 2010-12-01T05:29:00.130 に答える
2

関数を別のファイルに入れfindて、それを実行します。

シェル関数は、それらが定義されているシェルの内部にあります。findそれらを見ることができなくなります。

于 2010-12-01T05:29:14.273 に答える
0

直接ではありません。Find は、シェルではなく、別のプロセスで実行されています。

関数と同じ仕事をするシェルスクリプトを作成し、それを見つけることができます-exec

于 2010-12-01T05:27:57.737 に答える
-2

-exec私は完全に使用を避けます。xargsを使用します。

find . -name <script/command you're searching for> | xargs bash -c
于 2014-04-11T21:33:45.757 に答える