【问题标题】:Match pattern midline and insert newline in awk匹配模式中线并在 awk 中插入换行符
【发布时间】:2016-02-26 00:35:15
【问题描述】:

一直在尝试使用awk 及其gensub() 来匹配不在行首的模式,并在第一部分和匹配项之间插入换行符。

模式是匹配 MM/DD HH:MM:SS。

我的脚本splitatdate.awk

#!/usr/bin/awk -f
{
  if ( /.+[0-9][0-9][/][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] / ) {
    print gensub(/^\(.+\)\([0-9][0-9][/][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] \)/,"\\1\n\\2", "g")
  }
}

我的测试输入break-me.txt,其中包含我拥有的线型样本:

11/25 08:06:30 good text follows here
rs = ['yada yada11/25 08:07:41 more interesting stuff
rs = ['things with data: tag value
rs = ['yada yada data: 11/25 08:07:43 even more interesting stuff

我在 bash 中运行时得到的结果:splitatdate.awk break-me.txt 是:

rs = ['yada yada11/25 08:07:41 more interesting stuff
rs = ['yada yada data: 11/25 08:07:41 even more interesting stuff

匹配正确的行(那些不以日期开头的行)但没有插入新行,或者据我所知,做任何替换。

我想我会得到什么:

rs = ['yada yada
11/25 08:07:41 more interesting stuff
rs = ['yada yada data: 
11/25 08:07:41 even more interesting stuff

完整的任务是按原样回显每一行,但用换行符分割那些日期字符串不在开头的行。但我需要了解为什么这部分不起作用。如果有人有更好的工具,我不会挂断使用 awk,但想知道我做错了什么。

这是在带有 GNU awk 3.1.7 的 RHEL 6 上。

编辑:此脚本的答案:在 gensub() 内的捕获分组括号之前去掉反斜杠。

【问题讨论】:

    标签: regex awk


    【解决方案1】:

    去掉捕获组括号前的反斜杠 - 只需使用 (..),而不是 \(..\),因为后者是文字括号。

    您可能想改用它,这样您就不必指定正则表达式两次:

    $ awk 'match($0,/(.+)([0-9][0-9][/][0-9][0-9] [0-9][0-9](:[0-9][0-9]){2}.*)/,a) { print a[1] "\n" a[2]  }' file
    rs = ['yada yada
    11/25 08:07:41 more interesting stuff
    rs = ['yada yada data:
    11/25 08:07:43 even more interesting stuff
    

    它的 GNU awk 用于第三个参数 match() 但你还是在使用 gawk。

    【讨论】:

    • 删除我的 .awk 脚本中的反斜杠有效。谢谢。
    • 但是用'match()'复制/粘贴你的例子对我来说没有输出。
    • 您正在使用一个非常旧的 gawk(我认为我的已经很旧了,而且我在 4.1.3 上!),获取一个更新的,因为您缺少大量非常有用的功能,显然包括这个,请参阅gnu.org/software/gawk/manual/gawk.html#Feature-History。嗯,这表示 match() 的第三个参数是在 3.1 中引入的,如果 match() 不支持它,它应该会给你一个语法错误,所以 idk。脚本输出 NOTHING 的唯一方法是,如果正则表达式与您的输入数据不匹配,请尝试使用更简单的正则表达式进行调试。
    • 啊,我明白了 - 在旧的 gawks 中默认禁用像 {2} 这样的 RE 间隔 - 在脚本的开头添加 --re-interval 标志 (awk --re-interval '...') 或更改 (:[0-9][0-9]){2}到显式等效的:[0-9][0-9]:[0-9][0-9]。最重要的是 - 获取新版本的 gawk!
    • 是的,确实如此。 RHEL 6 使用旧版本的东西是因为它们想要稳定,无论好坏。在这种情况下,我坚持使用操作系统附带的东西。如您所说,添加--re-interval 会生成输出。非常感谢。如果有很多新功能,我必须小心使用在线帮助指南,以确保他们不是在谈论 v>3.1.7 中的功能。感谢您的警告。
    【解决方案2】:

    使用 GNU sed:

    $ sed -r 's|^(.+)([0-9]{2}/[0-9]{2} ([0-9]{2}:){2}[0-9]{2}.*)$|\1\n\2|' infile
    11/25 08:06:30 good text follows here
    rs = ['yada yada
    11/25 08:07:41 more interesting stuff
    rs = ['things with data: tag value
    rs = ['yada yada data: 
    11/25 08:07:43 even more interesting stuff
    

    这将捕获第一个捕获组中日期字符串之前的所有内容以及第二个捕获组中以日期字符串开头的所有内容,然后插入换行符。

    为保证一行不以日期字符串开头,我们要求在其前至少有一个字符 .+(“一个或多个任意”)。

    【讨论】:

    • 这解决了我遇到的分割线和回显未更改的线的真正问题。并且很高兴使用不同的正则表达式分隔符而不是“/”。我在 awk 中看不到如何做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多