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


57

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

find . -exec cmd1; cmd2

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

回答:


40

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

$ 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は評価されません。


ああ、私は忘れていました-o
イグナシオバスケス-エイブラムス

32

エラーコードが原因でcmd1がcmd2の実行を防止できるかどうかは問題ではありません0

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

両方のコマンドに常にこれを実行させる唯一の信頼できる方法findは、その後コマンドを順番に実行するシェルを起動することです。

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

2

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がスクリプトで定義したシェル関数を呼び出せないという事実を回避します。


0

私は以前の両方のソリューションを試してみましたが、運はあまりありませんでした。これは私のためにうまくいきました:

$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done

ファイルのリストが大きすぎる場合、これは機能しません。
アレックス

-3

tryコマンド:

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

4
ええ、それは良い考えではありません。*-execの部分は、現在のディレクトリ内のすべてのファイルに展開されます。特にとして実行する場合sudo
slhck
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.