2つの一致文字列のうちの1つが一致する場合、行を抽出する方法は?

2つの一致文字列のうちの1つが一致する場合、行を抽出する方法は?

以下に示すように、国名に関する情報を含む複数行のファイルがあります。

$cat country.txt

max_china_clean_foo
man_india_raw_bar
max_us_clean_bax
max_uk_raw_bar
max_canada_raw_foo
max_au_clean_bar

このファイルから国名を抽出したいと思います。現在、forループから国名を抽出するために以下のコードを使用しています。

val=${val#*_}
val=${val%_clean*}
echo $val

ただし、生成された出力にはchina, us国名のみがあるため、au以下のように残りの国を抽出するには少し変更して同様のコードを繰り返す必要があります。

val=${val#*_}
val=${val%_raw*}
echo $val

clean私はこれがそれをコーディングする明確な方法ではないので、raw文字列を含むすべての行から国名を抽出するのに役立つ必要があることを知っています。

awkまたはsedを使用して2つの一致するキーを持つすべての国名を抽出する方法はありますか?私の出力は次のようになります

china
india
us
uk
canada
au

ベストアンサー1

テキストを処理するためにシェルループを使用しない

ここでは、次のことができます。

cut -d _ -f 2 < country.txt

または、入力に_文字のない行を含めることができる場合:

awk -F _ 'NF >= 2 {print $2}' < country.txt

国名に文字を含めることができ、その行の最初の出現の間または後の部分を_返す場合は、次のようにします。__raw_clean

perl -ne 'print $1 if s/^[^_]*_(.*?)_(clean|raw)/' < country.txt

またはGNUを使用してくださいgrep

grep -Po '^[^_]*_\K.*?(?=_clean|_raw)' < country.txt

-P(PCREサポートで構築されている場合grep)正規表現はPerl互換正規表現です。これらの正規表現では、\K一致する文字列の先頭がリセットされ、プレビュー(?=...)演算子です。つまり、...一致する部分に含まれる残りの文字列で一致するものを探します。出力を一致する部分にします-o。したがって、ここでは上記と一致するものを印刷します。つまり、貪欲ではない同等物です。つまり、できるだけ短いゼロ個以上の文字シーケンス(この場合、ゼロ個以上の下線シーケンスの後に続く)です。 ()は()行を開始し、その後ろにアンダースコアが続き、後ろに続くか続くと見なされます。grep.*?.*[^_]*^_raw_clean

これを使用して、pcregrep次のように書くこともできます。

pcregrep -o1 '^[^_]*_(.*?)_(clean|raw)'

それを使用すると、-o1最初の部分と一致する部分が印刷されます(...)

おすすめ記事