【问题标题】:AWK Regex pattern matchingAWK 正则表达式模式匹配
【发布时间】:2014-09-15 22:08:23
【问题描述】:

我有一个文本文件,我需要在一个字段中识别特定模式。我正在使用 AWK,并尝试使用 match() 函数。

要求是我需要查看一串数字中是否存在以下模式

??????1?
??????3?
??????5?
??????7?

也就是说,我只对最后一位数字是 1、3、5 或 7 感兴趣。

我有一个解决方案,看起来像这样;

    b = match($23, "[0-9][0-9][0-9][0-9][0-9][0-9]1[0-9]")
    c = match($23, "[0-9][0-9][0-9][0-9][0-9][0-9]3[0-9]")
    d = match($23, "[0-9][0-9][0-9][0-9][0-9][0-9]5[0-9]")
    e = match($23, "[0-9][0-9][0-9][0-9][0-9][0-9]7[0-9]")

    if (b || c || d || e)
    {
            print "Found a match" $23
    }

我认为虽然我应该能够像这样更简洁地编写正则表达式;

b = match($23, "[0-9]{6}1[0-9]")

但这不起作用。

我是否遗漏了什么,或者我的正则表达式技能(不是很好)真的那么糟糕?

感谢期待

【问题讨论】:

  • 您一定对第 23 个字段感兴趣吗?我们能看到一整行数据吗?您的脚本的其余部分是否以任何方式转换该行?

标签: regex awk


【解决方案1】:

正则表达式分隔符是/.../,而不是"..."。当您在 RE 上下文中使用引号时,您是在告诉 awk 在字符串文字中存储了一个 RE,并且该字符串文字被解析两次,一次是在读取脚本时,然后在执行脚本时再次解析,这使得您的 RE 规范那么多适应这种双重解析更加复杂。

所以,不要写:

b = match($23, "[0-9]{6}1[0-9]")

写:

b = match($23, /[0-9]{6}1[0-9]/)

改为。

不过,这不是你的问题。您最可能遇到的问题是您调用的 awk 版本不支持像 {6} 这样的 RE 间隔。如果您使用的是旧版本的 GNU awk,则可以通过添加 --re-interval 标志来启用该功能:

awk --re-interval '...b = match($23, /[0-9]{6}1[0-9]/)...'

但无论是这样还是您使用的是不支持 RE_intervals 的 awk,最好的办法是获取更新版本的 gawk。

最后,您的整个脚本可以简化为:

awk --re-interval '$23 ~ /[0-9]{6}[1357][0-9]/{print "Found a match", $23}'

如果你愿意,可以将 [0-9] 更改为 [[:digit:]] 以实现语言环境独立性。

直到最近才在 gawk 中默认不支持 RE 间隔的原因是旧 awk 不支持它们,因此在旧 awk 中执行时具有a{2}b 的 RE 的脚本会一直在寻找那些5 chars 和 gawk 不希望旧脚本在 gawk 而不是旧 awk 中执行时安静地中断。为了方便我们向后兼容,一些发布者正确地决定冒险使用默认启用 RE 间隔。

【讨论】:

  • 很好的答案。谢谢不幸的是,我坚持使用我拥有的 awk 版本,服务器不是我来管理的。
  • 您确定您的服务器上只有 1 个 awk 版本吗?例如,Solaris 附带 3(/usr/bin/awk、/usr/bin/nawk 和 /usr/xpg4/bin/awk)。您是否碰巧知道您正在运行哪个 awk 版本(试试 awk --version 和/或告诉我们操作系统)?
  • 感谢您的 cmets,删除了我的答案并为您的答案投了赞成票——我不知道 AWK 的正则表达式风格,并提供了一些想法,希望语法兼容。
【解决方案2】:

这里有一个awk 解决方案:

awk -v FS="" '$7~/(1|3|5|7)/' file

通过将FS 设置为空,每个字符都成为一个字段。然后我们可以测试字段 #7。

正如汤姆所发布的那样。

awk -v FS="" '$7~/[1357]/' file

【讨论】:

  • 这并没有考虑输入包含许多字段的事实,只有其中一个要匹配。无论如何使用/[1357]/ 会更有意义。
猜你喜欢
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
相关资源
最近更新 更多