web-dev-qa-db-ja.com

複数のコマンドを使用した-execの検索

Find -execを複数のコマンドで使用しても成功しません。次のようなコマンドが可能かどうか誰かが知っていますか?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

基本的には、現在のディレクトリの各txtファイルの最後の行を印刷し、その行の最後にコンマとそれに続くファイル名を印刷しようとしています。

359
Andy

findは、コマンドに複数の-exec部分を受け入れます。例えば:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

この場合、@Calebで述べられているように、2番目のコマンドは最初のコマンドが正常に戻った場合にのみ実行されます。成功または失敗に関係なく両方のコマンドを実行したい場合は、次の構文を使用できます。

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;
546
Tinker
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
79
Avari

次のいずれか

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;
47

別の方法はこのようなものです:

multiple_cmd() { 
    tail -n1 $1; 
    ls $1 
}; 
export -f multiple_cmd; 
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

一行で

multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • "multiple_cmd()" - 関数です
  • "export -f multiple_cmd" - 他のサブシェルが見ることができるようにそれをエクスポートします
  • "find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - あなたの例で関数が実行されることを見つけます

このようにしてmultiple_cmdは必要に応じて長くて複雑になることがあります。

お役に立てれば。

13
Al3x

もっと簡単な方法があります。

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

あるいは

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"
8
Camilo Martin

Findでこれができるかどうかはわかりませんが、代わりの解決策はShellスクリプトを作成してfindで実行することです。

lastline.sh:

echo $(tail -1 $1),$1

スクリプトを実行可能にする

chmod +x lastline.sh

findを使う:

find . -name "*.txt" -exec ./lastline.sh {} \;
7

デニスの最初の答えは、トラブルを解決するための答えです。しかし実際には、タイトルが示すように1つのexecだけで複数のコマンドを使用した検索ではなくなりました。一つのexecにいくつかのコマンドで答えるためには、resolvするために何か他のものを探す必要があります。これが例です。

過去7日間に数回の{}参照を使用して1つのexecコマンドを使用して変更された最新の10000行の.logファイルを保存します。

1)コマンドがどのファイルに対して何をするかを確認します。

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2)それをしてください:(これ以上欲しいのは ">"だけで ">"だけではありません)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

4
Eric Duruisseau

Camilo Martinのおかげで、私は関連した質問に答えることができました。

私がやりたかったのは

find ... -exec zcat {} | wc -l \;

うまくいきませんでした。しかしながら、

find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done

動作しますので、ありがとうございます!

3
Greg Dougherty

xargs :)を使うべきです

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

もう一つ(osxで作業中)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'
1
smapira