awk将双引号字符串视为一个标记,并忽略其间的空格

Roy*_*han 25 unix bash awk

数据文件 - data.txt:

ABC "I am ABC" 35 DESC
DEF "I am not ABC" 42 DESC
Run Code Online (Sandbox Code Playgroud)

cat data.txt | awk '{print $2}'

将导致"I"而不是被引用的字符串

如何制作awk以便忽略引号中的空格并认为它是一个单一的令牌?

mab*_*enk 10

另一种选择是使用FPAT变量,该变量定义描述每个字段内容的正则表达式.

将此AWK脚本另存为parse.awk:

#!/bin/awk -f

BEGIN {
  FPAT = "([^ ]+)|(\"[^\"]+\")"
}
{
  print $2
}
Run Code Online (Sandbox Code Playgroud)

使其可执行chmod +x ./parse.awk并解析您的数据文件./parse.awk data.txt:

"I am ABC"
"I am not ABC"
Run Code Online (Sandbox Code Playgroud)

  • 这适用于 GNU awk,但不适用于 Mac OS X 附带的 awk,因此如果您使用的是 Mac,请执行“brew install gawk”。 (2认同)

Dig*_*oss 8

是的,这可以在awk中很好地完成.没有任何严重的黑客攻击,很容易获得所有领域.

(这个例子适用于The One True Awk和gawk.)

{
  split($0, a, "\"")
  $2 = a[2]
  $3 = $(NF - 1)
  $4 = $NF
  print "and the fields are ", $1, "+", $2, "+", $3, "+", $4
}
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于第二个位置上有单个引用字段且总共有4个字段的情况.这不是通用的.它将接受任何位置的任何引用字段的解决方案将是理想的. (11认同)
  • 格式化一个班轮:`cat data.txt | awk'拆分($ 0,a,"\""){$ 2 = a [2]} {$ 3 = $(NF - 1)} {$ 4 = $ NF} {print"且字段为",$ 1,"+ ",$ 2,"+",$ 3,"+",$ 4}'` (2认同)

Chr*_*egg 5

试试这个:

$ cat data.txt | awk -F\" '{print $2}'
I am ABC
I am not ABC
Run Code Online (Sandbox Code Playgroud)

  • @DigitalRoss - 很好的解决方案; 我没想过那种方法. (2认同)

小智 5

此问题的最佳答案仅适用于具有单引号字段的行。当我发现这个问题时,我需要一些可以适用于任意数量的引用字段的东西。

最终我在另一个线程中找到了Wintermute 的答案,他为这个问题提供了一个很好的通用解决方案。我刚刚对其进行了修改以删除引号。-F\"请注意,运行以下程序时需要调用 awk 。

BEGIN { OFS = "" } {
    for (i = 1; i <= NF; i += 2) {
        gsub(/[ \t]+/, ",", $i)
    }
    print
}
Run Code Online (Sandbox Code Playgroud)

这是通过观察当您用“-字符分隔时数组中的每个其他元素都将位于引号内来实现的,因此它会用逗号替换分隔不在引号中的空格。

然后,您可以轻松链接 awk 的另一个实例来执行您需要的任何处理(只需再次使用字段分隔符开关即可-F,)。

请注意,如果第一个字段被引用,这可能会中断 - 我还没有测试过它。不过,如果确实如此,如果该行的第一个字符是“,则通过添加 if 语句从 2 而不是 1 开始应该很容易修复。