【问题标题】:backslash in gawk fieldsgawk 字段中的反斜杠
【发布时间】:2023-04-10 17:15:01
【问题描述】:

我刚刚被要求使用 gawk 检查我的所有输出文件,我尽可能避免这样做。 怎么样

gawk 'NF \!= 6' file

不同于

gawk 'NF != 6' file 

即反斜杠如何改变这个表达式的含义?

是否应该输出字段数不是 6 且以反斜杠结尾的行?

我的文件出现以下错误:

gawk:    ^ backslash not last character on line

有人吗?

【问题讨论】:

    标签: bash awk gawk


    【解决方案1】:

    如果你使用双引号而不是单引号,那么! 是一个特殊字符,应该用反斜杠转义。重要的是,您正在转义感叹号,以便您的 shell 看不到它。

    gawk "NF \!= 6" file
    

    在双引号内,shell 将在将参数传递给 gawk 之前将 \! 转换为 !。调用 gawk 时,反斜杠已消失。

    但是,对于单个 qutoes,shell 将忽略 ! 字符,因此无需使用反斜杠转义它们。事实上,正如您发现的那样,这样做是一个语法错误,因为反斜杠最终会被传递给 gawk,这会导致意外的\

    【讨论】:

      【解决方案2】:

      没有反斜杠的行按预期工作。但是,如果您想知道,反斜杠通常用于转义特殊字符(它们失去了特殊含义并被用作自己),也用于分割长行,因此您可以编写如下内容(在 shell 下):

      $ gawk 'NF \
      != 6' file
      

      也会有同样的效果。

      你的例子特别棘手。您将字符串放在单引号内。这使得 shell 不会修改你所写的内容,并将其传递给程序。如果你使用你的反斜杠表达式,gawk 会在一个没有意义的地方找到一个 '\'(在 gawk 中它只用于分割长行和转义字符串中的字符)。在我用两行反斜杠编写的示例中,gawk 接收到由反斜杠分隔的两行(概念上是一行)。

      【讨论】:

        【解决方案3】:

        如果您尝试匹配没有 6 个字段且以反斜杠结尾的行,这是一种方法:

        gawk -v 'patt=\\\\$' 'NF != 6 && $0 ~ patt' file
        

        Gawk(和其他 AWK)有一些关于反斜杠转义的复杂规则。这就是为什么它们在前面的命令中有四个反斜杠。 (美元符号表示数据文件中输入行的结尾,就像在任何正则表达式中一样。)

        【讨论】:

          【解决方案4】:

          无论您使用双引号还是单引号,如果您使用的是类似 Bourne 的 shell,gawk 将看到与引号之间完全相同的程序。即使在双引号中,Bourne 和类似 csh 的 shell 也只在可能需要转义的字符之前使用 \(如 $,在 csh 的情况下,! - 因此在 csh 中,这个程序在语法上看起来对 gawk 是正确的,尽管它仍然不会不要做你想做的)。

          !在这种情况下没有意义,所以它给出了一个错误。要“输出字段数不是 6 且以反斜杠结尾的行”,请使用:

          gawk 'NF != 6 && /\\$/' file

          即:匹配不包含 6 个字段的行,并且匹配行尾 ($) 之前的 \。 \ 必须用另一个反斜杠转义,因为 gawk 也使用 \ 进行转义 - 尽管在 gawk 的情况下,all \(除了那些被另一个 \ 转义的除外)被吸收;那些没有转义特殊字符的则被简单地省略。

          如果没有关联动作,则在满足此条件语句时将执行默认动作(打印行)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-27
            • 1970-01-01
            • 2021-09-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多