【问题标题】:Passing Variable to NR in AWK command not working在 AWK 命令中将变量传递给 NR 不起作用
【发布时间】:2012-08-26 11:08:34
【问题描述】:

您好,在使用 awk 命令找到正则表达式后,我正在尝试打印 5 行。我有以下内容:

line_start=$(awk '/regex/{print NR}' file)
let line_end=$line_start+4
awk 'NR==$line_start, NR==$line_end' file

这不会打印任何内容。它没有挂起,只是继续下一行。

我研究了一些类似的问题,看到人们使用 -v 选项。我应该在这里使用它吗,他们的情况是针对较大的 awk 脚本。

顺便说一句,我正在使用 Kornshell

谢谢!

【问题讨论】:

    标签: shell unix awk ksh


    【解决方案1】:

    您可以为此使用 sed:

    sed -n '/regex/{N;N;N;N;N;p}' file
    

    或者改变awk解决方案:

    line_start=$(awk '/regex/{print NR}' file) 
    let line_end=$line_start+4 
    awk "{ if (NR>=$line_start && NR<=$line_end) print; }" file
    

    另一个awk解决方案(s.awk)

    BEGIN           { v = -1} 
    /regex/         { v = 0 } 
    v > -1          { v++   }
    v > -1 && v < 5 { print }
    v == 5          { exit  }
    

    使用:

    awk -f s.awk file
    

    【讨论】:

    • 在大多数情况下,在您发布的代码中,if 不是必需的。只需将条件放在操作块之外。这就是 OP 试图做的,也是 Gilles 在他的回答中所做的。
    • 非常感谢大家!我现在明白了很多!
    【解决方案2】:

    您的脚本有几个问题。直接的问题是,在第二次调用 awk 时,您在脚本周围使用了单引号,因此 $line_start$line_end 是由 shell 扩展的变量,它们作为脚本的一部分逐字传递给 awk。您可以改用双引号来解决此问题。

    awk "NR==$line_start, NR==$line_end" file
    

    这只是因为$line_start$line_end 是数字。如果它们是字符串,则不能这样做,因为 shell 变量的值最终会被 awk 解析为 awk 代码的一部分,而不是字符串。一般来说,要将字符串传递给 awk 脚本,您可以使用带有 -v 的惯用语来定义与 shell 变量同名的 awk 变量(如果您愿意,也可以使用不同的名称):

    awk -v "line_start=$line_start" -v "line_end=$line_end" 'NR==line_start, NR==line_end' file
    

    您的脚本还有更多问题。

    • 您对文件进行了两次解析。如果文件很大,这可能会很慢,如果数据来自管道而不是磁盘文件,则不可能。
    • 如果/regex/ 有多个匹配项,则$line_start 将包含行号列表。 shell 将在let 行报错语法错误。

    如果您想在匹配后显示 5 行,请在 awk 中进行计数。

    awk '
      /regex/ { show_lines = 5 }
      show_lines { print; --show_lines; }
    ' file
    

    如果您只想显示第一个匹配的块,请在show_lines 达到 0 时退出。

      show_lines { print; --show_lines; if (!show_lines) exit; }
    

    【讨论】:

    • 哇!你们太棒了,非常感谢!我没有所有这些信息。非常详细的回答谢谢!
    猜你喜欢
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多