50

1つのファイルでgrepを実行し、一致するたびにコマンドを実行するにはどうすればよいですか?

ファイル:

foo
bar
42
foo
bar

dateたとえば、のすべての一致に対して実行するために実行したいと思いfooます。

次の試行は機能しません:

grep file foo | date %s.%N

どうやってするか?

4

6 に答える 6

47
grep file foo | while read line ; do echo "$line" | date %s.%N ; done

スクリプトでより読みやすく:

grep file foo | while read line
do
    echo "$line" | date %s.%N
done

入力の各行について、readは値を変数に入れ$line、ステートメントはとwhileの間のループ本体を実行します。値はstdinではなく変数に含まれるようになったため、以前はstdinにプッシュバックしていましたが、dateがそのように機能すると仮定すると、実行できます。dodoneechodate %s.%N "$line"

常にスペースを壊し、これがファイルのリストを読み取るための悪夢になるfor line in `grep file foo`ため、類似したものの使用は避けてください。for

 find . -iname "*blah*.dat" | while read filename; do ....

で失敗しforます。

于 2012-11-15T16:39:00.183 に答える
21

本当に必要なのはxargsコマンドです。http://en.wikipedia.org/wiki/Xargs

grep file foo | xargs date %s.%N

Cygwin環境でいくつかのファイルを照合し、照合を完全なWindowsパスに変換する例

$ find $(pwd) -type f -exec ls -1 {} \; | grep '\(_en\|_es\|_zh\)\.\(path\)$' | xargs cygpath -w
于 2013-12-02T14:30:58.777 に答える
5
grep command_string file | sh - 
于 2017-10-30T19:30:16.087 に答える
3

Linuxには、そのための興味深いコマンドがありますxargs。これにより、前のコマンド(grep、ls、findなど)からの出力をカスタム実行の入力として使用できますが、カスタム実行を可能にするいくつかのオプションがあります。並列コマンド。いくつかの例の下:

あなたの質問に基づいて、file.txtの「 foo 」の一致ごとに「%s。%N 」の形式で日付を出力する方法は次のとおりです。

grep "foo" file.txt | xargs -I {} date +%s.%N

より興味深い使用法は、一致ごとにファイルを作成することですが、この場合、一致が同一である場合、ファイルはオーバーライドされます。

grep "foo" file.txt | xargs -I {} touch {}

作成したファイルにカスタム日付を連結する場合

grep "foo" file.txt | xargs -I {} touch "{}`date +%s.%N`"

一致するものがファイル名であり、それらのバックアップを作成したいとします。

grep "foo" file.txt | xargs -I {} cp {} "{}.backup"

そして最後に、backupNameでカスタム日付を使用するxargsの場合

grep "foo" file.txt | xargs -I {} cp {} "{}`date +%s.%N`"

xargsの並列実行などのオプションの詳細については、 https ://en.wikipedia.org/wiki/Xargsにアクセスし、日付形式については、https ://www.thegeekstuff.com/2013/05/date-command-examples/にアクセスしてください。

さらに、このシナリオで役立つコマンドの通常の方法も見つけました。これは単純ですが、以下の例は、上記の例と同等です。

for i in `grep "foo" test.txt`; do date +%s.%N; done
for i in `grep "foo" test.txt`; do touch ${i}; done
for i in `grep "foo" test.txt`; do touch "${i}`date +%s.%N`"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2`date +%s.%N`"; done

楽しんで!!!

于 2020-05-22T05:13:05.343 に答える
0

grepには--line-buffered、一致する各行を出力するオプションが必要な場合があります。そうでない場合、一致行を出力する前に最大4Kバイトをバッファリングします。これにより、ここでの目標が無効になります。

tail -f source | grep --line-buffered "expression | xargs ...
于 2019-08-05T09:49:10.810 に答える
0
    grep search_string files_to_search | sh
于 2020-02-24T08:50:20.760 に答える