我试图在匹配后获取下一条记录的确切字段,例如,如果" string1"匹配在$ 2然后我需要获得下一记录的$ 2的值。我有大约100个这样的字符串来匹配每个在输入文件中出现一次的字符串。但是相同的搜索字符串可以出现在不同的输入文件中(我有超过1000个这样的输入文件)。
示例输入:逗号分隔
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot02,
RX RF Frequency Slot02,Channel Spacing Slot02,AMR Range (QPSK) Slot02,AMR Range (16QAM) Slot02
37740.500 [MHz],7 [MHz],Enable,Enable
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot03,
RX RF Frequency (Slot03),Channel Spacing (Slot03),AMR Range (QPSK) {(Slot03)|(SW GRP2)},AMR Range (16QAM) {(Slot03)|(SW GRP2)}
37712.500 [MHz],7 [MHz],Enable,Enable
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot04,
RX RF Frequency Slot04,Channel Spacing Slot04,AMR Range (QPSK) Slot04,AMR Range (16QAM) Slot04
,,,
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot05,
RX RF Frequency (Slot05),Channel Spacing (Slot05),AMR Range (QPSK) {(Slot05)|(SW GRP3)},AMR Range (16QAM) {(Slot05)|(SW GRP3)}
string1,string2 ....是搜索模式包含字母数字与({|介于两者之间。 值字段可以为空。 字段数不固定。 string1的位置不固定。可能出现在不同的位置,但只会在文件中出现一次。
到目前为止我尝试了什么:
BEGIN {
FS=OFS=","
}
{for (i=1;i<=NF;i++){
if ($i == "string1"){
getline val;
split(val,a,",");
am1=a[i]}
if ($i == "string2"){
getline val;
split(val,a,",");
am2=a[i]}
}
}
END {print am1,am2}
我知道这对于给定的输入不起作用,因为i因连续的value1和value2而被更改。我应该为每个搜索字符串使用不同的for循环吗?或建议任何解决方案。
搜索
string1="AMR Range (QPSK) Slot02",string2="AMR Range (QPSK) {(Slot03)|(SW GRP2)}",string3="AMR Range (QPSK) Slot04",string4="AMR Range (16QAM) Slot02"
期望的输出:
10.217.250.162,NTTN_EMS,Enable,Enable,,Enable
答案 0 :(得分:1)
我不了解你的输出格式,但也许这会有所帮助。这会创建搜索关键字到相应下一行中的值的映射
更改了您的上一个输入行
$ cat file
blah,blah,blah,string1,string2,string3,blah
blah,blah,blah,value1,value2,value3,blah
string4,blah,string5,string6,blah
value4,x,value5,value6,x
并创建一个单独的查找文件
$ cat lookup
string1
string2
string3
string4
string5
string6
最后是剧本
$ awk -F, 'NR==FNR{m[$0];next}
FNR==1{p=$0;next}
{n=split(p,a);
for(i=1;i<=n;i++) if(a[i] in m) print a[i],$i;
p=$0}' lookup file
生成输出
string1 value1
string2 value2
string3 value3
string4 value4
string5 value5
string6 value6
您也可以使用多个数据文件运行相同的脚本
$ awk ... lookup file1 file2 file3 ...
并且可能在打印中添加FILENAME以识别哪个文件是匹配的来源。
答案 1 :(得分:0)
我不明白你如何从发布的样本输入中获得已发布的预期输出,但是给出了这个输入:
$ cat strings
AMR Range (QPSK) Slot02
AMR Range (QPSK) {(Slot03)|(SW GRP2)}
AMR Range (QPSK) Slot04
AMR Range (16QAM) Slot02
$ cat file
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot02,
RX RF Frequency Slot02,Channel Spacing Slot02,AMR Range (QPSK) Slot02,AMR Range (16QAM) Slot02
37740.500 [MHz],7 [MHz],Enable,Enable
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot03,
RX RF Frequency (Slot03),Channel Spacing (Slot03),AMR Range (QPSK) {(Slot03)|(SW GRP2)},AMR Range (16QAM) {(Slot03)|(SW GRP2)}
37712.500 [MHz],7 [MHz],Enable,Enable
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot04,
RX RF Frequency Slot04,Channel Spacing Slot04,AMR Range (QPSK) Slot04,AMR Range (16QAM) Slot04
,,,
10.217.250.162,NTTN_EMS,Radio / AMR Configuration Slot05,
RX RF Frequency (Slot05),Channel Spacing (Slot05),AMR Range (QPSK) {(Slot05)|(SW GRP3)},AMR Range (16QAM) {(Slot05)|(SW GRP3)}
我认为以下内容符合您在文中所描述的内容:
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR { strings[$0]; next }
FNR==1 { out = $1 OFS $2 }
{
if (pos) {
out = out OFS $pos
pos = 0
}
for (i=1; i<=NF; i++) {
if ($i in strings) {
pos = i
}
}
}
ENDFILE {
if (pos) {
out = out OFS $pos
pos = 0
}
print out
}
$ awk -f tst.awk strings file
10.217.250.162,NTTN_EMS,Enable,Enable,
上面使用GNU awk for ENDFILE而不是END,所以你可以这样做:
awk -f tst.awk strings file1 file2 ....
或类似的同时处理多个文件。
如果您的字符串必须在您的awk脚本中进行硬编码,那么它只是一个调整:
$ cat tst.awk
BEGIN {
FS=OFS=","
split("AMR Range (QPSK) Slot02\n\
AMR Range (QPSK) {(Slot03)|(SW GRP2)}\n\
AMR Range (QPSK) Slot04\n\
AMR Range (16QAM) Slot02", tmp, /\n/)
for (i in tmp) {
strings[tmp[i]]
}
}
FNR==1 { out = $1 OFS $2 }
{
if (pos) {
out = out OFS $pos
pos = 0
}
for (i=1; i<=NF; i++) {
if ($i in strings) {
pos = i
}
}
}
ENDFILE {
if (pos) {
out = out OFS $pos
pos = 0
}
print out
}
$ awk -f tst.awk file
10.217.250.162,NTTN_EMS,Enable,Enable,