1つのファイルでgrepを実行し、一致するたびにコマンドを実行するにはどうすればよいですか?
ファイル:
foo
bar
42
foo
bar
date
たとえば、のすべての一致に対して実行するために実行したいと思いfoo
ます。
次の試行は機能しません:
grep file foo | date %s.%N
どうやってするか?
1つのファイルでgrepを実行し、一致するたびにコマンドを実行するにはどうすればよいですか?
ファイル:
foo
bar
42
foo
bar
date
たとえば、のすべての一致に対して実行するために実行したいと思いfoo
ます。
次の試行は機能しません:
grep file foo | date %s.%N
どうやってするか?
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がそのように機能すると仮定すると、実行できます。do
done
echo
date %s.%N "$line"
常にスペースを壊し、これがファイルのリストを読み取るための悪夢になるfor line in `grep file foo`
ため、類似したものの使用は避けてください。for
find . -iname "*blah*.dat" | while read filename; do ....
で失敗しfor
ます。
本当に必要なのは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
grep command_string file | sh -
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
楽しんで!!!
grepには--line-buffered
、一致する各行を出力するオプションが必要な場合があります。そうでない場合、一致行を出力する前に最大4Kバイトをバッファリングします。これにより、ここでの目標が無効になります。
tail -f source | grep --line-buffered "expression | xargs ...
grep search_string files_to_search | sh