我刚刚被要求使用 gawk 检查我的所有输出文件,我尽可能避免这样做。如何
gawk 'NF \!= 6' file
与......不同
gawk 'NF != 6' file
也就是说,反斜杠如何改变这个表达式的含义?
它应该输出字段数不是 6 并以反斜杠结尾的行吗?
我的文件出现以下错误:
gawk: ^ backslash not last character on line
有人吗?
如果您使用双引号而不是单引号,则!
它是一个特殊字符,应使用反斜杠进行转义。重要的是,您正在转义感叹号,以便您的外壳看不到它。
gawk "NF \!= 6" file
在双引号内,shell 将在将参数传递给 gawk 之前转换\!
为。!
调用 gawk 时,反斜杠消失了。
但是,对于单引号,shell 将忽略!
字符,因此无需使用反斜杠转义它们。事实上,正如您所发现的那样,这样做是一个语法错误,因为反斜杠最终被传递给 gawk,这会在意想不到的\
.
没有反斜杠的行按预期工作。但是,如果您想知道,反斜杠通常用于转义特殊字符(它们失去了特殊含义并被用作自己),也用于分割长行,因此您可以编写类似(在 shell 下)的内容:
$ gawk 'NF \
!= 6' file
它会产生同样的效果。
特别是你的例子有点棘手。您将字符串放在单引号内。这使得 shell 不会修改你所写的内容,并将其传递给程序。如果您使用反斜杠表达式,gawk 会\
在没有意义的地方找到一个 ' '(在 gawk 中,它仅用于分割长行和转义字符串中的字符)。在我用两行反斜杠编写的示例中,gawk 接收到由反斜杠分隔的两行(概念上是一行)。
如果您尝试匹配没有 6 个字段且以反斜杠结尾的行,这是一种方法:
gawk -v 'patt=\\\\$' 'NF != 6 && $0 ~ patt' file
Gawk(和其他 AWK)有一些关于反斜杠转义的复杂规则。这就是为什么它们在前面的命令中是四个反斜杠。(与任何正则表达式一样,美元符号表示数据文件中输入行的结尾。)
无论您使用双引号还是单引号,如果您使用的是类似 Bourne 的 shell,gawk 将完全按照引号之间的方式看到程序。即使在双引号中,Bourne 和类似 csh 的 shell 也只在可能需要转义的字符之前使用 \(如 $,在 csh 的情况下,! - 因此在 csh 中,这个程序在语法上看起来对 gawk 是正确的,尽管它仍然不会不要做你想做的)。
!在这种情况下没有意义,所以它给出了一个错误。要“输出字段数不为 6 且以反斜杠结尾的行”,请使用:
gawk 'NF != 6 && /\\$/' file
即:匹配不包含 6 个字段的行,并且匹配行尾 ($) 之前的 \。\ 必须用另一个反斜杠转义,因为 gawk 也使用 \ 进行转义 - 尽管在 gawk 的情况下,所有\(除了被另一个 \ 转义的那些)都被吸收;那些没有逃脱特殊字符的就被简单地省略了。
如果没有关联操作,则在满足此条件语句时将执行默认操作(打印行)。