【问题标题】:How do awk match and ~ operators work together?awk 匹配和 ~ 运算符如何协同工作?
【发布时间】:2017-05-25 20:56:43
【问题描述】:

我无法理解这个 awk 代码:

$0 ~ ENVIRON["search"] {
  match($0, /id=[0-9]+/);
  if (RSTART) {
    print substr($0, RSTART+3, RLENGTH-3)
  }
}
  1. ~match() 运算符如何相互交互?

  2. 如果match() 的输出没有被打印或回显,它有什么影响?它实际上返回或做什么?如何在我自己的代码中使用它?

这与Why are $0, ~, &c. used in a way that violates usual bash syntax docs inside an argument to awk? 相关,但这个问题的中心是理解 bash 和 awk 语法之间的区别,而这个问题的中心是理解脚本的 awk 部分。

【问题讨论】:

  • into an algorithm 是什么意思,你是说进入伪代码吗?或者你只是问它是如何工作的?您可能想尝试阅读手册。
  • 你已经被告知 - 这不是 bash,它是 awk。阅读 Arnold Robbins 所著的 Effective Awk Programming,第 4 版。
  • 在代码块之后的第一段中专门回答问题,您对awk '$0 ~ /ab/' 的解释是正确的:您提供的代码是有条件的,而 awk 在给定条件时执行的默认操作是{ print $0 },当条件为真时打印整行。 (相比之下,如果您只给它一个块并且没有描述何时运行它的条件,awk 将无条件地为每一行输入运行该块。
  • ...所以,如果您运行printf '%s\n' abcd efgh ijkl | awk '$0 ~ /ab/',则只有printf 发出的三行中的第一行将依次由awk 处理。
  • ...match 的棘手之处在于它实际上并没有返回字符串;相反,它返回一个整数,并根据它在哪里找到它正在搜索的正则表达式来设置单独的变量(RSTARTRLENGTH)。见gnu.org/software/gawk/manual/html_node/String-Functions.html

标签: awk


【解决方案1】:

一次回答一个问题:

  1. ~match() 运算符如何相互交互?

他们没有。至少不是直接在您的代码中。 ~ 是正则表达式比较运算符。在$0 ~ ENVIRON["search"] 的上下文中,它用于测试环境变量search 中包含的正则表达式是否作为当前记录($0) 的一部分存在。如果是,则执行后续{...} 块中的代码,如果不是,则不是。

  1. match() 有什么影响,如果它的输出没有被打印或 回应?

它标识与作为第二个参数提供的正则表达式匹配的第一个参数 ($0) 中的第一个子字符串的起点(并将其存储在 awk 变量 RSTART 中)和长度 (RLENGTH) (id=[0-9]+)。使用 GNU awk,它还可以使用圆括号标识的匹配字符串段(也称为“捕获组”)填充第三个数组参数。

  1. 它实际上返回或做什么?

它返回 RSTART 的值,如果没有找到匹配项,则返回 0,否则返回 1 或更大。对于它的作用,请参见上一个答案。

  1. 如何在自己的代码中使用它?

如您发布的示例中所示,这是一种方法,但该代码更通常写为:

($0 ~ ENVIRON["search"]) && match($0,/id=[0-9]+/) {
    print substr($0, RSTART+3, RLENGTH-3)
}

在第一部分使用字符串而不是正则表达式比较可能更合适:

index($0,ENVIRON["search"]) && match($0,/id=[0-9]+/) {
    print substr($0, RSTART+3, RLENGTH-3)
}

获取 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书,了解如何使用 awk。

【讨论】:

  • 这就是我正在寻找的确切答案。感谢您的耐心和知识。
【解决方案2】:
  • 使用正则表达式id=[0-9]+ 在每一行中查找匹配项
  • 如果匹配的起始位置 (RSTART) 不为 0,则:
  • 打印没有id=的匹配

这更短,但作用相同:

xinput --list | grep -Po 'id=[0-9]+' | cut -c4-

【讨论】:

  • 是问代码是如何工作的,而不是重写它。
  • 如果你必须在 Stackoverflow 上询问才能理解代码,代码可能过于复杂。所以重写它以提高可读性绝对是一种选择。
  • 不,不是,你无法决定问题应该是什么。
猜你喜欢
  • 2012-09-21
  • 2020-05-13
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 2014-07-28
  • 1970-01-01
  • 2021-12-09
  • 2019-04-21
相关资源
最近更新 更多