find を使用するときに複数のコマンドを実行するにはどうすればよいですか?

find を使用するときに複数のコマンドを実行するにはどうすればよいですか?

見つけたものに対して複数のコマンドを実行しようとしていますが、どうすればこれを実現できますか?

find . -exec cmd1; cmd2

動作しないようです。代わりに、すべてのファイルで cmd1 が実行された後に cmd2 が実行されます。

答え1

このデモでは、最初の にsh -c 'echo first; false'(または)を使用します。これにより、出力が生成され、選択した終了コードの効果も得られます。次に、2 番目の に が使用されます。現在のディレクトリにファイルが 1 つあると仮定します。true-exececho second

$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second

このタイプの実際のコマンドは次のようになります。

find . -type f \( -exec command1 \; -false -o -exec command2 \; \)

2 番目のセットでは、エスケープされた括弧が 2 つの-exec節をグループ化します。-false間の により、テスト状態が "false" に強制され、 により、-o次の式 (2 番目の-exec) が評価されます-false

からman find

expr1 expr2
連続する 2 つの式は暗黙の「and」で結合されていると見なされます。expr1 が false の場合、expr2 は評価されません。

expr1 -a expr2
expr1 expr2 と同じです。

expr1 -o expr2
または; expr1 が true の場合、expr2 は評価されません。

答え2

エラー コードが原因で cmd1 が cmd2 の実行を阻止できるかどうかを気にしない場合は、次の操作を実行します0

find . -exec cmd1 \; -exec cmd2 \;

両方のコマンドを常に実行させる唯一の確実な方法は、findコマンドを順番に実行するシェルを呼び出すことです。

find . -exec bash -c 'cmd1; cmd2' filedumper {} \;

答え3

cmd1 と cmd2 を実行するスクリプトを作成しても構わない場合は、次のようになります。

find . -exec myscript {} \;

または

find . -exec myscript {} +

myscript が一度に複数のファイルを処理できるかどうかに応じて、\; または + を使用します (ファイル名にスペースなどが含まれている場合は扱いにくくなります)。

私の経験では、自分がやっていたことをスクリプトに書き込むことは、ほとんどの場合、価値があります。一度やらなければならないことは、もう一度やらなければなりません。

しかし、巧妙なトリックは、見つけたものを内部スクリプト:

if [ $# -gt 0 ]; then
    for each; do
        touch $each
    done
else
    find . -exec $0 {} +
fi

次に、myscript は引数として指定したファイルに対して動作しますが、引数を指定しない場合は、現在のディレクトリから find を実行し、見つかったファイルに対して自身を呼び出します。これにより、スクリプトで定義したシェル関数を find -exec が呼び出せないという問題を回避できます。

答え4

コマンドを試してください:

sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l

関連情報