【问题标题】:gawk NR and match issuesgawk NR 和匹配问题
【发布时间】:2020-07-01 20:11:13
【问题描述】:

我需要使用正则表达式来解析数据文件的特定行。我的带有 match 的测试命令有效,我的特定行号的测试命令有效,但是当我把它们放在一起时,我没有得到任何输出。

gawk 'NR==42 {print $0}' filename

打印出整个第 42 行

gawk 'match($0, /([0-9]+)/, a) {print NR ":" a[1]}' filename

有很多打印输出,但具体有以下输出: 42:137674 所以,我的第 42 行有一个数字匹配

gawk 'NR==42 match($0, /([0-9]+)/, a) {print NR ":" a[1]}' filename

不打印任何东西,我不知道为什么。

我有一个解决方法:

gawk 'match($0, /([0-9]+)/, a) {if (NR==42) print NR ":" a[1]}' filename

但我认为它的性能较低,所以想弄清楚为什么其他命令不起作用

编辑: 已回答,我完全忘记了 NR 和 match 之间的 &&

【问题讨论】:

  • 使用&& 逻辑和?
  • omg,我太笨了,太累了,谢谢,我刚刚忘记了 &&,奇怪的是它只是安静地死掉而不是抛出错误
  • awk 工具的语法非常宽松。如果不能将相邻的表达式合二为一,它将始终尝试连接它们。在这种情况下,match() 返回值 '1' 附加到 '42',所以这个模式只会匹配第 421 行。

标签: awk


【解决方案1】:

快速回答:问题的解决方案是添加缺少的and-运算符:

NR==42 && match($0, /([0-9]+)/, a) 
 

OP 中发生了什么?

Awk 程序通常写成一组模式-动作对:

pattern { action }

pattern 为真时执行action

上面使用的pattern为:

NR==42 match($0, /([0-9]+)/, a)

由于运算符的优先顺序,实际上类似于:

NR == (42  match($0, /([0-9]+)/, a))

让我们假设,例如,我们在NR==42。 match 函数返回 01 取决于是否找到匹配项。如 OP 中所述,match 函数在NR==42 的情况下返回1pattern 现在阅读:

42 == (42 1)

expr expr 形式的运算符类似于字符串连接,所以在 awk 中处理为

42 == ("42" "1")
42 == "421"

运算符== 是一个数值运算符当且仅当两个操作数都是自然数值。但是"421"是一个字符串,所以它会把NR的数值转换成一个字符串:

"42" == "421"

这是错误的,因此action 将不会被执行。

注意:当且仅当match 函数在420 行返回false 或在421 行返回true 时,才会执行上述操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多