2012-05-06 9 views
2

私たちは、私は次のテキストがあるとしましょう:次のように...、grepの出力にどのようにラベルを付けることができますか?

name is test1 and age is test2 end 
name is test3 and age is test4 end 
name is test5 and age is test6 end 
name is test7 and age is test8 end 

私はtest1のためにgrepをしています、TEST2:

-bash$ grep -o -P "is .*? and|is .*? end" test 
is test1 and 
is test2 end 
is test3 and 
is test4 end 
is test5 and 
is test6 end 
is test7 and 
is test8 end 

を私がするいくつかのテキストを付加することができる方法があります一致パターン?私はこのような出力を探しています:

STRING1:is test1 and 
STRING2:is test2 end 
STRING1:is test3 and 
STRING2:is test4 end 
STRING1:is test5 and 
STRING2:is test6 end 
STRING1:is test7 and 
STRING2:is test8 end 

答えて

2

あなたが(確かに、それは非常にきれいではありません)パイプラインでsedを使用することができます。

$ grep -o -P "is .*? and|is .*? end" test | sed '/and$/s/^/STRING1:/; /end$/s/^/STRING2:/' 
STRING1:is test1 and 
STRING2:is test2 end 
STRING1:is test3 and 
STRING2:is test4 end 
STRING1:is test5 and 
STRING2:is test6 end 
STRING1:is test7 and 
STRING2:is test8 end 

/.nd$/各置換がラインに作用する置換を制限する前にその正規表現に一致する。 grepの出力は、あなたのニーズを満たすためにawkにする

+0

+1はお時間をいただき、ありがとうございます。実際には、私の唯一の関心事は、正規表現の数が増えた場合、 'sed'ですべてを繰り返す必要があるということですね。それとも私は何かが欠けている?そして、終わりの言葉がはっきりしない場合があります。私が達成しようとしているのは、grepが探しているものを「ラベル付けする」方法を見つけることです。 – Legend

+0

各マッチに任意の文字列がある場合は、すべての解決方法が必要です。しかし、合理的なアルゴリズム関係があれば、awk(またはPythonまたはPerl)スクリプトを書くことができ、すべてを書き出す必要はありません。また、マッチした行そのものが十分なラベルではないのでしょうか? (また、終わりの単語が足りない場合は、 'sed'と' grep'の違いを考慮して、正規表現全体をsedスクリプトに入れてください。) – huon

+0

ありがとうございました!それは役に立ちます。 – Legend

3

Iパイプは:

grep -o -P "is .*? and|is .*? end" test | \ 
awk -v a=STRING1: -v b=STRING2: "/and$/ {print a\$0} /end$/ {print b\$0}" 
+0

'/と$ /'と '/ end $ /'を使って行の最後にあることを確認してください。 – huon

+0

@dbauppはい、そうです。私はこれがほんの一例だと思う、あなたは他のパターンにそれを調整することができます。 –

0

あなたが操作したいだけのテキストを選択していないので、sedgrepよりも仕事のための優れたツールとなるでしょう。

あなたが望む置換を実行する正規表現を構築するのは簡単です。 2つの置換があるので、2つの式(-e)を使用できます。一致する行だけを操作するには(grepの例のように)、一致する行のみを出力するには、sed -npアクションを使用します。トリッキーな部分は、同じ行に複数回操作したいということですが、最初の置換を実行すると、2回目の置換の残りの文字列が失われます。最初の式が2番目の式が一致していることを文字列が削除されますので、たとえば、次はあなたが望むものに近いですが、2番目の式が一致しません:

sed -n -e 's/.*\(is .* and\).*/STRING1:\1/p' -e 's/.*\(is .* end\)/STRING2:\1/p' 
STRING1:is test1 and 
STRING1:is test3 and 
STRING1:is test5 and 
STRING1:is test7 and 

この問題を回避するには、使用することができますhと保持バッファ(h)にパターンスペース(入力ライン)をコピーして、次のsedコマンド(g)のために戻ってパターンスペースにそれをコピーするためのコマンドをsedのg:置換する前に

sed -n -e 'h;s/.*\(is .* and\).*/STRING1:\1/p' -e 'g;s/.*\(is .* end\)/STRING2:\1/p' 
STRING1:is test1 and 
STRING2:is test2 end 
STRING1:is test3 and 
STRING2:is test4 end 
STRING1:is test5 and 
STRING2:is test6 end 
STRING1:is test7 and 
STRING2:is test8 end 

最初の式が実行されると、行は保存されますdを保持バッファに格納する。 2番目の式は最初にパターンバッファにホールドバッファをロードし、2番目の置換が機能するようにします。

あなたは一つにこれら二つの別々の式を組み合わせることができ、私はそれを読み、それが難しくなります考える:

sed -n -e 'h;s/.*\(is .* and\).*/STRING1:\1/p;g;s/.*\(is .* end\).*/STRING2:\1/p' 
関連する問題