使用awk提取多个字符串
我试图从每行中提取两个字符串,有些行没有这两个字符串,有些行只有一个字符串 My input.txt:使用awk提取多个字符串,awk,match,Awk,Match,我试图从每行中提取两个字符串,有些行没有这两个字符串,有些行只有一个字符串 My input.txt: ID=MD001;refer=init;loc=tap2 ID=MD002;Name=Jam;refer=init;loc=tap2 ID=MD003;Name=Jane;Value=vip;refer=init;loc=tap2 ID=MD008;Name=George;product=car;vall=some;Value=vim;refer=init;loc=tap2 ID=MD0010
ID=MD001;refer=init;loc=tap2
ID=MD002;Name=Jam;refer=init;loc=tap2
ID=MD003;Name=Jane;Value=vip;refer=init;loc=tap2
ID=MD008;Name=George;product=car;vall=some;Value=vim;refer=init;loc=tap2
ID=MD0010;product=cars;Value=vip4;refer=init;loc=tap2
ID=MD0018;product=cars;
...
我希望匹配字符串名称或/和值,并将其输出为:
ID=MD002 Name=Jam
ID=MD003 Name=Jane Value=vip
ID=MD008 Name=George Value=vim
ID=MD0010 Value=vip4
我试过:
head input.txt | awk'$1~/Name | Value/{match$1,/ID=*;*Name*;*Value.*/,Name;打印名[1]名[2]名[3]'
但它确实打印了任何东西。
谢谢你的帮助。你能试试下面的吗
awk '
BEGIN{
FS=";"
}
{
for(i=2;i<=NF;i++){
if($i~/^Name|^Value/){
val=(val?val OFS:"")$i
}
}
if(val){
print $1,val;
}
val=""
}
' Input_file
从这个开始:
$ cat tst.awk
BEGIN { FS="[=;]" }
{
delete f
for (i=1; i<NF; i+=2) {
f[$i] = $i "=" $(i+1)
}
print f["ID"], f["Name"], f["Value"]
}
$ awk -f tst.awk file
ID=MD001
ID=MD002 Name=Jam
ID=MD003 Name=Jane Value=vip
ID=MD008 Name=George Value=vim
ID=MD0010 Value=vip4
ID=MD0018
另一个类似的awk
然而
$ awk -F\; '{ # set the delim
for(i=2;i<=NF;i++) # looping from the 2nd field
if($i~/^(Name|Value)/) { # looking for keywords and if found
for(i=1;i<=NF;i++) # restart loop from beginning
if($i~/^(Name|Value)/||i==1) # outputing first field and matches
printf "%s ",$i
print "" # newline in the end
# next # breaking from the 1st loop not needed
}
}' file
这可能非常适合awk的FPAT特性,其中字段由其内容而不是分隔符定义。看
FPAT定义了3个可能的字段。第一个ID=[^;\v]+,意味着它必须以ID=开头,后跟至少一个既不是分号也不是垂直空格的字符。接下来的两个字符,Name=[^;\v]+和Value=[^;\v]+,同样的意思是Name=或Value=后跟至少一个既不是分号也不是垂直空格的字符。这是否回答了您的问题?当您申请时,您可以很容易地完成{print map[ID,full]、map[Name,full]、map[Value,full]}等行请求的操作。欢迎您。请注意,您也可以重新排列列,以便按您想要的任何顺序输出它们,您不需要;不必按照输入的顺序输出。是的,通过更改f[]中的列名,可以打印出所需的列。晚饭谢谢Ed
$ cat tst.awk
BEGIN { FS="[=;]" }
{
delete f
for (i=1; i<NF; i+=2) {
f[$i] = $i "=" $(i+1)
}
hit = 0
out = f["ID"]
out = out val("Name")
out = out val("Value")
}
hit { print out }
function val(tag) {
if (tag in f) {
hit = 1
return (OFS f[tag])
}
}
$ awk -f tst.awk file
ID=MD002 Name=Jam
ID=MD003 Name=Jane Value=vip
ID=MD008 Name=George Value=vim
ID=MD0010 Value=vip4
$ awk -F\; -v p='(Name|Value)=' '
$0~p {printf "%s ", $1;
for(i=2; i<=NF; i++) if($i~p) printf "%s ", $i;
print ""}' file
ID=MD002 Name=Jam
ID=MD003 Name=Jane Value=vip
ID=MD008 Name=George Value=vim
ID=MD0010 Value=vip4
$ awk -F\; '{ # set the delim
for(i=2;i<=NF;i++) # looping from the 2nd field
if($i~/^(Name|Value)/) { # looking for keywords and if found
for(i=1;i<=NF;i++) # restart loop from beginning
if($i~/^(Name|Value)/||i==1) # outputing first field and matches
printf "%s ",$i
print "" # newline in the end
# next # breaking from the 1st loop not needed
}
}' file
ID=MD002 Name=Jam
ID=MD003 Name=Jane Value=vip
ID=MD008 Name=George Value=vim
ID=MD0010 Value=vip4
awk '
BEGIN {
FPAT = "(ID=[^;\v]+)|(Name=[^;\v]+)|(Value=[^;\v]+)"
}
NF>1 {
# Only prints lines that have Name and/or Value
for (i=1; i<NF; i++) {
printf $i " "
}
print $NF
}
' file