【问题标题】:Pass variable to awk pattern将变量传递给 awk 模式
【发布时间】:2018-09-28 22:18:04
【问题描述】:

我正在编写一个调用 awk 脚本的 shell 脚本,然后我使用 getline 在 BEGIN 中获取一些用户输入,并将输入保存到一些变量中。

BEGIN {printf "What's the word?"
getline word < "-"
}

现在,其中一个变量称为“单词”,我想在脚本中的另一种模式中使用它来打印包含给定单词的所有行。我尝试过这样的事情:

/(^| )word( |$)/ 

它将打印包含单词“word”的所有行,我知道它不会起作用,因为它不被识别为变量。我搜索了很多,发现以

开头的模式
$0~

但在我的情况下它也不起作用。有没有办法可以将变量传递给此模式并打印包含存储在变量中的单词的所有行?

【问题讨论】:

  • 您没有使用How do I use shell variables in an awk script? 中的模式是否有原因?
  • 我知道 -v 选项可用于变量,但这会将它从 shell 传递到 awk 脚本,我尝试读取 BEGIN 部​​分中的输入而不是 shell 本身.
  • 坦率地说,从 shell 而不是从 awk 进行读取让我感到震惊,因为在大多数情况下这是明智的方法——如果需要,您的 awk 脚本的输入可以来自非终端源。但是... 耸耸肩,您比我更了解您的运行时上下文,并且与这里提出的问题正交。

标签: regex shell awk glob


【解决方案1】:

另一种选择是使用单词边界,您可以在变量中应用一些反斜杠转义

 awk -v v="\\\y$word\\\y" '$0~v' file

不确定所有awks 都支持这个。或者,您可以使用\&lt;\&gt; 作为左右边界。

【讨论】:

    【解决方案2】:

    如果您使用 BEGIN 部​​分来构建具有完整模式的变量,您可以稍后参考:

    awk -v word="hello" '
      BEGIN {
        pattern = "(^|[[:space:]])" word "([[:space:]]|$)"
      }
    
      $0 ~ pattern { print $0 }
    '
    

    ...也就是说,如果您不介意为每一行重构模式的开销,您甚至不需要这样做:

    awk -v word="hello" '$0 ~ ("(^|[[:space:]])" word "([[:space:]]|$)") { print $0 }'
    

    (为什么是[[:space:]] 而不是?这样制表符和除十六进制20 普通空格之外的其他空白字符也可以用作单词分隔符)。

    【讨论】:

    • 谢谢!我要试试这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 2014-01-05
    • 2014-09-09
    相关资源
    最近更新 更多