【发布时间】:2023-04-10 17:15:01
【问题描述】:
我刚刚被要求使用 gawk 检查我的所有输出文件,我尽可能避免这样做。 怎么样
gawk 'NF \!= 6' file
不同于
gawk 'NF != 6' file
即反斜杠如何改变这个表达式的含义?
是否应该输出字段数不是 6 且以反斜杠结尾的行?
我的文件出现以下错误:
gawk: ^ backslash not last character on line
有人吗?
【问题讨论】:
我刚刚被要求使用 gawk 检查我的所有输出文件,我尽可能避免这样做。 怎么样
gawk 'NF \!= 6' file
不同于
gawk 'NF != 6' file
即反斜杠如何改变这个表达式的含义?
是否应该输出字段数不是 6 且以反斜杠结尾的行?
我的文件出现以下错误:
gawk: ^ backslash not last character on line
有人吗?
【问题讨论】:
如果你使用双引号而不是单引号,那么! 是一个特殊字符,应该用反斜杠转义。重要的是,您正在转义感叹号,以便您的 shell 看不到它。
gawk "NF \!= 6" file
在双引号内,shell 将在将参数传递给 gawk 之前将 \! 转换为 !。调用 gawk 时,反斜杠已消失。
但是,对于单个 qutoes,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 的情况下,all \(除了那些被另一个 \ 转义的除外)被吸收;那些没有转义特殊字符的则被简单地省略。
如果没有关联动作,则在满足此条件语句时将执行默认动作(打印行)。
【讨论】: