AWK:行のパターン位置に関係なく、2つのカスタムフィールド区切り文字の間でパターンを抽出する方法は?

AWK:行のパターン位置に関係なく、2つのカスタムフィールド区切り文字の間でパターンを抽出する方法は?

以下はファイルの1行の断片です。

LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1

「MIC」タグの値を抽出することに興味があります。つまり、私が望む出力は次のようになります。

XAIM

完全なコード行はかなり長いです。

20200403: #379 IT0005215329 {CU=EUR, GTPID=144115188076657542, II=IT0005215329, IS=18814564, LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1, SN=801670, STY=ORDINARY, TK="0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200", TS=FF, TY=S, UQ=1}

ライン上の「MIC」ラベルの位置は常に同じではありません。

私はかなり多くのチュートリアルを読んでおり、すべてのソリューションはカスタムフィールド区切り文字を作成し、行のパターン位置を使用して目的のパターンを抽出するようです。

たとえば、私は次に与えられた例に従おうとしました。このスレッドつまり、このコードを使用して「MIC」タグから値を抽出します。

awk 'BEGIN {FS="MIC=|,"} {print $2}' input.txt

次の結果が表示されます。

GTPID=144115188076657542

上記の完全な行の例を確認すると、出力は「=」記号を持つ2番目のタグ「GTPID」の値です。最初に、私はこれが{FS="MIC=|,"}「2つのカスタムフィールド区切り文字を生成することを意味すると思いました。最初のものは、MIC=2番目はです,{print $2}

ただし、上記のコードは、「=」記号を含むすべてのパターンの値を印刷するようです。この記号はその行の 2 番目の記号です。

その間のMIC=値を抽出する方法は,

答え1

f[]データに名前と値のペアがある場合は、まずマッピング(下)をキャプチャする配列を作成し、その名前で目的のフィールドにアクセスできることをお勧めします。たとえば、次のようになります。

$ awk -F'[=,] *' '{for (i=1;i<NF;i+=2) f[$i]=$(i+1); print f["MIC"]}' file
XAIM

テスト値を調整し、他のフィールドをランダムな順序で印刷するなどの作業がどれほど簡単かを確認してください。

awk -F'[=,] *' '
    { for (i=1;i<NF;i+=2) f[$i]=$(i+1) }
    (f["MIC"] == "XAIM") && (f["LN"] ~ /FOOD/){ print f["SG"], f["RIC"] }
' file
MA1 FF.MI

答え2

$ sed -n 's/.* MIC=\([^,}]*\).*/\1/p' file
XAIM

これは、文字列をsed一致させ、行全体をその文字列に置き換えるために使用されます。他のすべてのデータは削除されます。 MIC=SOMETHING,MIC=SOMETHING}SOMETHING


$ tr ',' '\n' <file | awk -F '=' '$1 == " MIC" { print $2 }'
XAIM

まず、すべてのコンマを改行で置き換え、次に文字をフィールド区切り文字としてawk使用します=。最初のフィールドが同じ場合、 MIC2番目のフィールドを印刷します。


$ awk -F ',' '{ for (i = 1; i <= NF; ++i) if (sub(" MIC=","",$i)) print $i }' file
XAIM

これはawk入力のみを受け取り、カンマで区切られたフィールドとして扱います。すべてのフィールドを繰り返し、フィールドが文字列で始まる場合、 MIC=その文字列はフィールドから削除され、残りの部分が印刷されます。


ファイルがJSON形式の場合(データを変換したようです。)~からJSONは、ほとんどのREST APIがJSON形式でデータを返し、そのデータが金融株式市場に関連しているように見えるため、ある時点ではJSONです。

{
  "CU": "EUR",
  "GTPID": 144115188076657540,
  "II": "IT0005215329",
  "IS": 18814564,
  "LN": "FINE FOODS & PHARMACEUTICALS NTM",
  "MIC": "XAIM",
  "RIC": "FF.MI",
  "SG": "MA1",
  "SN": 801670,
  "STY": "ORDINARY",
  "TK": "0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200",
  "TS": "FF",
  "TY": "S",
  "UQ": 1
}

もしそうなら、jq最も簡単です。

$ jq -r '.MIC' file1
XAIM

答え3

ANDgrepと.は、一致するデータcutのみをgrep -o取得し、o要求されたフィールドと値を見つけるために使用されます。これをフィールド区切り文字として入力し、cut2番目のフィールドを取得します。=

$ grep -o 'MIC=[^,]*' input | cut -d= -f2
XAIM

そしてsed。一致するサブパターンを使用し()て抽出し、要求されたフィールド/値のペアを見つけます\1

$ sed -nE 's/^.*MIC=([^,]+).*$/\1/;p' input
XAIM
# or, alternatively,
$ sed -n 's/^.*MIC=\([^,]*\).*$/\1/;p' input
XAIM

そしてawk。フィールド区切り記号とレコード区切り記号をそれぞれと=に設定します,。パターンが一致するレコードの場合は、2番目のフィールド(つまり値)を印刷します。

$ awk 'BEGIN { FS="="; RS=","; } $1 ~ /MIC/ { print $2 }' input
XAIM

答え4

注文する

 awk -F "," '{for(i=1;i<=NF;i++){if($i ~ /MIC/){gsub(/.*=/,"",$i);print $i}}}' 

ファイル名

出力

XAIM

関連情報