在 awk 中打印匹配的字段分隔符

Posted

技术标签:

【中文标题】在 awk 中打印匹配的字段分隔符【英文标题】:Print matched field separators in awk 【发布时间】:2015-02-04 11:55:32 【问题描述】:

鉴于以下记录

01-01-2012 18:02 some data 01-11-2014 20:22 some other data 10-02-2014 14:00 more data still

我正在尝试对日期、时间和数据进行分组,并将它们打印在单独的行上,如下所示:

01-01-2012 18:02 some data
01-11-2014 20:22 some other data
10-02-2014 14:00 more data still

但是,到目前为止我所拥有的:

echo '01-01-2012 18:02 some data 01-11-2014 20:22 some other data 10-02-2014 14:00 more data still' | awk -F '[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*' ' for ( n=1; n<=NF; n++ ) print $n 

结果:

 some data 
 some other data 
 more data still

缺少日期和时间。它们是字段分隔符,因此不会打印。

如何修改我的 awk 脚本以打印与正则表达式匹配的每个字段分隔符?

【问题讨论】:

【参考方案1】:

通过 awk

awk 'for (i=1;i<=NF;i++) printf ($i~/-..-/)?RS $i:FS $i' infile

解释

for loop:逐个读取元素,元素被空格分割。 printf : 打印元素不返回 printf ($i~/-..-/)?RS $i:FS $i - 可以扩展为 if-else 语句: if ($i~/-..-/) print RS $i) else (print FS $i)

【讨论】:

如果模式 [0-9]+-[0-9]+-[0-9]+ 出现在数据中,则中断【参考方案2】:

方法

awk 'for(i=2;i<=NF;i++)if($i~/[0-9]+-[0-9]+-[0-9]+/)$i="\n"$i1' file

【讨论】:

您忘记通过1print 打印结果 @matsjoyce 怎么尴尬? @matsjoyce 是的,我在发表评论后注意到了一秒钟哈,今天做了一场噩梦! 如果模式 [0-9]+-[0-9]+-[0-9]+ 出现在数据中,则中断【参考方案3】:

使用 gnu awk:

awk -v RS='[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+' '!NFs=RT;next print s $0' file
01-01-2012 18:02 some data
01-01-2012 18:02 some other data
01-01-2012 18:02 more data still

编辑:您可以使用非 gnu awk:

awk 'gsub(/[[:blank:]]+[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+/, "\n&"); 
      gsub(/\n[[:blank:]]+/, "\n") 1' file
01-01-2012 18:02 some data
01-11-2014 20:22 some other data
10-02-2014 14:00 more data still

也可以使用grep -P

grep -oP '[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+.+?(?=[0-9]+-[0-9]+-[0-9]+|$)' file
01-01-2012 18:02 some data
01-11-2014 20:22 some other data
10-02-2014 14:00 more data still

【讨论】:

见我上面的评论:awk only 谢谢,如果模式[0-9]+-[0-9]+-[0-9]+ 出现在数据中,这不会中断。我使用 ox X 的免费 BSD awk(非 GNU)。 是的,没错。我还在 BSD awk(在 OSX 上)上对其进行了测试。

以上是关于在 awk 中打印匹配的字段分隔符的主要内容,如果未能解决你的问题,请参考以下文章

Bash awk 打印匹配的分隔符

二十八awk

awk简单用法

匹配两个文件之间的两个字段 AWK

如何从管道分隔的文件中打印字段?

7.5