grep 文字列の 2 つの部分を正確に一致させる

grep 文字列の 2 つの部分を正確に一致させる

以下のように grep コマンドを使用して文字列の一部を取得するにはどうすればよいですか?

弦:

orange:"orange", red:"apple", purple:"grape", yellow:"banana", green:"watermelon"
red:"strawberries", yellow:"lemon"

私が欲しいもの:

red:"apple" yellow:"banana"
red:"strawberries" yellow:"lemon"

私はこれを試しました:

grep -oP '(red:\"[^\"]*).*(yellow:\"[^\"]*)'

答え1

.*真ん中の はすべて、つまり の部分と一致しますpurple:"grape"。代わりに (GNU grep を使い続けると仮定すると)、各部分を(foo|bar)「OR」構造で個別に一致させます。

grep -oP '(red|yellow):\"[^\"]*"'

注意: 閉じ を追加する必要がありました"。また、 をエスケープする必要はないので"、次のように使用できます。

grep -oP '(red|yellow):"[^"]*"'

いずれにせよ、これはあなたに

red:"apple"
yellow:"banana"

次に、線と線の間にスペースを入れてつなぎます。

grep -oP '(red|yellow):"[^"]*"' | paste -sd ' ' -

正直に言うと、代わりに当然使いますsed

sed -n 's/.*\(red:"[^"]*"\).*\(yellow:"[^"]*"\).*/\1 \2/p'

答え2

grep通常、オフラインのコンテンツを抽出しません。正規表現pに一致する行を出力します(一般的に、コマンドにちなんで命名されます)。regg/re/p ed

grepただし、使用していると思われるGNU などの一部の実装では、-o拡張機能としてその一部を実行する必要があります。

pcregrepさらに進んで、-oオプションの数値引数を取ることで、行の一致した部分全体ではなく、キャプチャ グループの内容を出力できます。

pcregrep -o1 -o2 --om-separator=' ' '(red:"[^"]*").*(yellow:"[^"]*")'

それでもできることには限界があります。

行から情報を抽出し、さらに変換を行うには、他のユーザーがここで示したように、代わりにテキストsストリームが必要になります。ed

答え3

確かにgrepSparhawk の提案または、ほぼ同じ次のコードを使用します。

$  echo 'red:"apple", purple:"grape", yellow:"banana"' |      
        grep -oP '(red|yellow):".+?"' | perl -00pe 's/\n/ /'
red:"apple" yellow:"banana"

個人的には、おそらく次のようにしますperl:

$ echo 'red:"apple", purple:"grape", yellow:"banana"' | 
    perl -F, -ane 'map{print if /red|yellow/}@F'
red:"apple" yellow:"banana"

関連情報