在 awk 中,如何在原始 $0 分隔符完好无损的情况下打印一系列字段?

在 awk 中,如何在原始 $0 分隔符完好无损的情况下打印一系列字段?

awk当子字符串的位置和长度基于原始 $0 中字段的位置时,如何提取 $0, in 的子字符串?

它实际上相当于删除第一个n. 铅字段和最后一个n.踪迹字段以及所有这些字段的前导和尾随分隔符,从原始的 $0 开始

举个例子:目前只知道范围是 4 美元到 8 美元(含)。
分隔符是任意数量的空格和/或单个逗号,例如。" , "或者只是","......并且前导分隔符将被忽略。

          Input: "   a  a  a   X marks   the   start,   Y   marks the  end  "
Expected Output: "X marks   the   start,     Y"

答案1

awk 不记得字段位置或分隔符字符串。您必须手动找出字段位置。这不是很难。

echo "   a  b  c   X marks   the   start,   Y   marks the  end  " |
awk '{
    i=1; n=1; tmp=$0;  # i=field number, n=column number
    while (match(tmp, / *, *| +/)) {
        A[i]=n; B[i]=n+RSTART-1;     # A[i],B[i] = start,end of delimiter i
        ++i; n+=RSTART+RLENGTH-1;
        tmp=substr(tmp,RSTART+RLENGTH)
    }
    print substr($0, A[5], B[9]-A[5])   # start at 4+1 because the first field is empty
}'

答案2

这可以是一个解决方案,只要没有制表符作为分隔符

#!/usr/bin/awk -f

  {
    start = index($0, " " $4 " ")
    stop  = index($0, " " $8 " ")
    print substr($0, start+1, stop - start + length($8))
  }

答案3

就目前情况而言,它适用于带或不带前导分隔符的数据,但如果任何字段包含“正则表达式敏感”数据,则会失败。解决方法是用正则表达式点 .{field of field} 替换每个字段...这是一个链接 到这样的版本...它很笨拙,但不会因为上述问题而崩溃:

awk 'BEGIN { FS = "([ \t]+)|([ \t]*,[ \t]*)" }
{ # Ignore leading delimiter, if present 
  hasLeadDlm = match($0, "^("FS")")
  LeadDlm = substr($0, 1, RLENGTH)
  if (hasLeadDlm) { sub("^("FS")", ""); }    # delete leading whitespace 
  sub("^"$1"("FS")"$2"("FS")"$3"("FS")", "") # delete leading fields
  match( $0, "^"$1"("FS")"$2"("FS")"$3"("FS")"$4"("FS")"$5)
  print substr($0, 1, RLENGTH)
}' <<< \
"a    X  a   X marks   the   start, ssY   marks the  end  
 a    X  a   X   marks the   start,  sY   marks the  end  
  a   X  a   X marks     the start,   Y   marks the  end  
   a  X  a   X marks   the     start ,Y   marks the  end  
    a   X  a   X marks   the   start,sssY   marks the  end"

相关内容