AWK:如何擷取 2 個自訂欄位分隔符號之間的模式,無論模式在行上的位置為何?

AWK:如何擷取 2 個自訂欄位分隔符號之間的模式,無論模式在行上的位置為何?

這是文件中一行的片段:

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

如果您檢查我上面提供的整行範例,輸出是帶有“=”符號的第二個標籤“GTPID”的值。起初我認為這{FS="MIC=|,"}意味著「建立兩個自訂欄位分隔符,第一個是MIC=,第二個是,,出於某種原因,我希望這{print $2}會列印這兩個欄位分隔符之間的任何內容。

但顯然上面的程式碼列印了包含符號“=”的任何模式的值,該符號恰好是該行的第二個。

如何提取 到 then 之間的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,orMIC=SOMETHING}字串,並用該字串替換整行SOMETHING。所有其他數據都將被丟棄。


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

首先用換行符號替換所有逗號,然後awk使用=字元作為字段分隔符號運行。當第一個欄位等於 時 MIC,列印第二個欄位。


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

這只使用awk輸入並將其視為逗號分隔欄位。它迭代所有字段,當字段以 string 開頭時 MIC=,該字串將從字段中刪除並列印其餘部分。


如果檔案是 JSON 格式(我想你可能已經轉換了數據JSON 在某些時候,因為大多數 REST API 會傳回 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

grepcut.用於僅grep -o獲取o匹配的數據,查找請求的欄位和值。將其作為欄位分隔符號cut輸入到 ,並取得第二個欄位:=

$ 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。將欄位分隔符號和記錄分隔符號分別設為=,。對於具有匹配模式的記錄,列印第二個欄位(即值):

$ 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

相關內容