Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用awk提取多个字符串_Awk_Match - Fatal编程技术网

使用awk提取多个字符串

使用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

我试图从每行中提取两个字符串,有些行没有这两个字符串,有些行只有一个字符串

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;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