awk多重分隔符和打印多列

awk多重分隔符和打印多列,awk,Awk,我正在尝试从日志输出创建CSV文件 示例:日志文件的两行: May 24 2013 18:13:24 ROUTER1 %%01IFNET/4/UPDOWN(l): The state of interface GigabitEthernet0/0/22 was changed to DOWN. May 24 2013 17:59:33 ROUTER1 %%01FIB/3/REFRESH_END(l): FIB refreshing end, the refresh group map is 0!

我正在尝试从日志输出创建CSV文件

示例:日志文件的两行:

May 24 2013 18:13:24 ROUTER1 %%01IFNET/4/UPDOWN(l): The state of interface GigabitEthernet0/0/22 was changed to DOWN.
May 24 2013 17:59:33 ROUTER1 %%01FIB/3/REFRESH_END(l): FIB refreshing end, the refresh group map is 0!
预期产出:

May 24 2013 18:13:24,ROUTER1,01IFNET,4,UPDOWN,The state of interface GigabitEthernet0/0/22 was changed to DOWN.
May 24 2013 17:59:33,ROUTER1,01IFNET,3,REFRESH_END,FIB refreshing end, the refresh group map is 0!
使用此awk命令,我可以成功地获得少量正确的部分:

cat test.log | awk -F'[" "%%/(l)]' '{print $1" "$2" "$3","$4","$5","$8","$9","$10","}'
输出:

May 24 2013 18:13:24,ROUTER1,01IFNET,4,UPDOWN,
May 24 2013 17:59:33,ROUTER1,01IFNET,3,REFRESH_END,

但是如何捕获“(l):“如“FIB刷新结束,刷新组映射为0!”或“接口GigabitEthernet0/0/22的状态更改为关闭”之后的多列描述文本。”。请告知。

Awk可以处理多个分隔符:

$ awk -F'[(/% ]' '{printf "%s",$1" "$2" "$3" "$4" "$5","$8","$9","$10",";for(i=12;i<=NF;i++)printf "%s ",$i;print ""}' file
May 24 2013 18:13:24 ROUTER1,01IFNET,4,UPDOWN,The state of interface GigabitEthernet0 0 22 was changed to DOWN.
May 24 2013 17:59:33 ROUTER1,01FIB,3,REFRESH_END,FIB refreshing end, the refresh group map is 0!

$awk-F'[(/%]'{printf“%s”、$1“$2“$3“$4“$5”、“$8”、“$9”、“$10”、”,for(i=12;i由于这是单行上的一个简单子项,所以我只使用sed,例如:

$ cat file
May 24 2013 18:13:24 ROUTER1 %%01IFNET/4/UPDOWN(l): The state of interface GigabitEthernet0/0/22 was changed to DOWN.
May 24 2013 17:59:33 ROUTER1 %%01FIB/3/REFRESH_END(l): FIB refreshing end, the refresh group map is 0!

$ sed -r 's/(([^ ]+ +){3}[^ ]+) +([^ ]+)[ %]+([^/]+)\/([^/]+)\/([^(]+)[^ ]+ +(.*)/\1,\3,\4,\5,\6,\7/' file
May 24 2013 18:13:24,ROUTER1,01IFNET,4,UPDOWN,The state of interface GigabitEthernet0/0/22 was changed to DOWN.
May 24 2013 17:59:33,ROUTER1,01FIB,3,REFRESH_END,FIB refreshing end, the refresh group map is 0!
但如果您愿意,这里有一个awk解决方案:

$ awk -F' %%|[(][^)+][)]: ' -v OFS="," '{$1=substr($1,1,20) OFS substr($1,22); gsub(/\//,OFS,$2)}1' file
May 24 2013 18:13:24,ROUTER1,01IFNET,4,UPDOWN,The state of interface GigabitEthernet0/0/22 was changed to DOWN.
May 24 2013 17:59:33,ROUTER1,01FIB,3,REFRESH_END,FIB refreshing end, the refresh group map is 0!

并不是说这不会从您的第一行输入中删除“Gigabit…”文本,因为您没有说明如何识别它-是您想删除“interface”之后的文本还是以“Gigabit”开头的文本,还是在一些空格或其他数字之后的文本?

我希望删除“interface”之后的内容不是打字错误

又脏又快:(不过应该有更好的办法……)


你是对的。事实上,这是一个打字错误:|::(我的错..对不起。实际上我不打算删除“接口”后的文本。无论如何谢谢你的回复:)谢谢你的回复..事实上我不想删除“千兆位…”…不幸的是,那是一个打字错误。:)谢谢,这正是我需要的!sudo_O,什么是-F'[(/%]“match?
-F
用于设置数据分隔符,其中值是正则表达式
[(/%]
,它定义了一个包含字符
/
%
或单个空格的字符类。基本上,类中的任何字符都不会被视为数据,而是作为分隔符。可能的重复项
awk -F'\\(l\\): ' -v OFS="," '{gsub(" %%|/"," ",$1);gsub(/ /,",",$1);for(i=1;i<=3;i++)sub(/,/," ",$1)}$2~/of interface /{gsub(/interface.*/,"interface",$2)}1' file
May 24 2013 18:13:24,ROUTER1,01IFNET,4,UPDOWN,The state of interface
May 24 2013 17:59:33,ROUTER1,01FIB,3,REFRESH_END,FIB refreshing end, the refresh group map is 0!