最初の列に一致する文字列を見つけるにはどうすればよいですか?

最初の列に一致する文字列を見つけるにはどうすればよいですか?

match_E2一致する文字列(sum pattern_2)と最初の列のみを取得しようとしています。

abcd.corp;;a123,Virtual,aws,Linux,Linux,match_E2,Database
web1.corp;;,Virtual,azure,match_E2,Linux,corpo,Database
web2.corp;;match_E2,Virtual,a2responsible,Linux_Suse,Linux,corpo,Database
web3.corp;;Virtual,Virtual,corpo,pattern_2,Linux,corpo,Database
web4.corp;;Virtual,Virtual,corpo,,Linux,pattern_2,Database

期待される出力は、以下より低い場合があります。

abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
web3.corp,pattern_2
web4.corp,pattern_2

-oオプションを試しましたが、grep一致する文字列のみを提供します。

答え1

あえて言えば、あなたの出来事はよりうまくいくでしょうsed

パターンの場合match_E2

$ sed -nE 's/^([^;]+).*(match_E2).*/\1,\2/p' file.txt

パターンの場合pattern_2

$ sed -nE 's/^([^;]+).*(pattern_2).*/\1,\2/p' file.txt

2つのモードを同時に使用するには:

$ sed -nE 's/^([^;]+).*(match_E2|pattern_2).*/\1,\2/p' file.txt

つまり、基本的には次のようになります。

$ sed -nE 's/^([^;]+).*(    ).*/\1,\2/p' file.txt
#                       ^  ^
#                       |  |
#            ---------------------
# put within these two parentheses the same (Extended Regular Expression) pattern you would use with `grep -E`

;最初のフィールドと残りの行の間の区切り文字の1つ以上にのみ依存することに注意してください。

答え2

次のawkコマンドは必要な操作を実行する必要があります。

awk -F'[;,]' -v pat="match_E2" '$0~pat{for (i=3;i<NF;i++) {if ($i ~ pat) printf("%s,%s\n",$1,$i)}}' file.txt
  • このオプションは、およびをフィールド区切り文字として認識し、それに応じて行を分割するように-F'[;,]'指示します。awk;,POSIX標準では、これらの複数文字フィールド区切り文字を完全な正規表現として解釈する必要がありますが、awkこの機能を正しく実装していないバージョンがある可能性があります。

  • モードは、-v pat="match_E2"コマンドラインオプションを介してモードを介してawkに渡されます。これにより、パターンは完全な正規表現として解釈されます。この文脈でその中にある文字が特別な意味を持っているなら、エスケープする必要があります!

  • 現在の行がパターンと一致する場合(「行全体が$0 ~ patどこかに格納されているpat正規表現と一致する場合」を意味)、すべての関連フィールド(フィールド3は最後のフィールドの後の最初のフィールド;)を繰り返し、実際の一致するフィールド(条件if ($i ~ pat))を識別しますします。次に、最初のフィールド($1)に一致するフィールド()を印刷してこれを実行します$iprintf()これは、一致する行に対応するフィールドが1つしかないことを前提としています。

複数のパターンを探している場合は、pat次のように正規表現を定式化できます。

awk -F'[;,]' -v pat="match_E2|pattern_2" ' ... etc ... '

または、各モードに対して1回、コマンドを2回実行します。

答え3

grep -o次の機能を使用するawkのバージョンに似ていますmatch

$ awk -F';' 'match($0,/match_E2|pattern_2/) {print $1 "," substr($0,RSTART,RLENGTH)}' file
abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
web3.corp,pattern_2
web4.corp,pattern_2

答え4

これは完全なリテラル文字列のマッチングを実行するため、ターゲット文字列に正規表現メタ文字が含まれている場合、または入力に部分文字列として表示される場合にも機能します。

$ awk '
    BEGIN { strs["match_E2"]; strs["pattern_2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
web3.corp,pattern_2
web4.corp,pattern_2

部分一致と完全一致の例については、次の入力を検討してください。

$ cat file
abcd.corp;;a123,Virtual,aws,Linux,Linux,mismatch_E2,Database
web1.corp;;,Virtual,azure,match_E2,Linux,corpo,Database
web2.corp;;match_E2,Virtual,a2responsible,Linux_Suse,Linux,corpo,Database
web3.corp;;Virtual,Virtual,corpo,pattern_275,Linux,corpo,Database
web4.corp;;Virtual,Virtual,corpo,,Linux,pattern_2,Database

入力の最初の行にはmismatch_E2andが含まれ、match_E24行目にはpattern_275and and notが含まれますpattern_2。さて、上記のawkスクリプトを実行し、予想される出力が生成されていることを確認してください。

$ awk '
    BEGIN { strs["match_E2"]; strs["pattern_2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
web1.corp,match_E2
web2.corp,match_E2
web4.corp,pattern_2

正規表現と文字列の一致の例を見るには、入力match_E2の1行を次に変更し、4行を次に変更します。m.*2patch_2p.*2

$ cat file
abcd.corp;;a123,Virtual,aws,Linux,Linux,m.*2,Database
web1.corp;;,Virtual,azure,m.*2,Linux,corpo,Database
web2.corp;;m.*2,Virtual,a2responsible,Linux_Suse,Linux,corpo,Database
web3.corp;;Virtual,Virtual,corpo,pattern_2,Linux,corpo,Database
web4.corp;;Virtual,Virtual,corpo,,Linux,pattern_2,Database

上記のawkスクリプトを修正して、m.*2andの代わりp.*2に予想される出力が生成されることを再確認しました。match_E2pattern_2

$ awk '
    BEGIN { strs["m.*2"]; strs["p.*2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
abcd.corp,m.*2
web3.corp,p.*2

関連情報