这是文件中一行的片段:
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
与grep
和cut
.用于仅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