使用 awk 将文件拆分为列
split file into columns with awk
我有一个如下所示的文件:
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
现在我想把它分成三列,例如:
1.2.3.4 1.2.3.4 Affected
www.addr.de 2.3.4.5 not Affected
我为此使用 awk:cat filename.txt | awk -F "[=()'']" '{print }'
但我仍然无法连续获得三列。我该如何解决?第二个问题:有没有比awk更好的选择?
您可以取消设置记录分隔符以单独读取每个块,如下所示:
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
$ awk -F'[]=():[:space:][]+' -v RS= '{print , , (NF==8?" " :"")}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
最后的三元处理两个不同数量的字段(7 或 8,取决于 "Affected" 或 "not Affected")。如果有8个字段,那么在space之后打印第7个,否则什么都不打印。
为了获得更整齐的格式输出,您可以使用 printf
而不是 print
:
$ awk -F'[]=():[:space:][]+' -v RS= '{printf "%-12s%10s %s%s%s", , , , (NF==8?" " :""), ORS}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
格式说明符规定了每个字段的宽度。 -
导致内容左对齐。 ORS
是输出记录分隔符,在您的平台上默认为换行符。
就列对齐而言,这取决于您要查找的是人类可读还是机器可读的内容。如果您想将此数据导入电子表格,也许您可以使用制表符 \t
(例如)分隔每一列,这可以通过将 -v OFS='\t'
添加到我的第一个版本来完成回答。
您需要将该部分作为一条记录来阅读,您可以在 GAWK 中使用 RS=
(无)来完成此操作。这会将块读取为记录。
awk -vRS= -F"[)(=\n]+" '{print }' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
还有一些awk
输入
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
Affected
2. result = www.addr.com (2.3.4.5)
not Affected
输出
$ awk 's{print [=11=]}s=/^[0-9]+\./{ gsub(/[()]/,"");printf ("%s %s", ,);next}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
--编辑--修改输入
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
输出
$ awk '{gsub(/[()\[\]]/,"")}s{="";print [=13=]}s=/^[0-9]+\./{printf ("%s %s", ,);next}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
我有一个如下所示的文件:
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
现在我想把它分成三列,例如:
1.2.3.4 1.2.3.4 Affected
www.addr.de 2.3.4.5 not Affected
我为此使用 awk:cat filename.txt | awk -F "[=()'']" '{print }'
但我仍然无法连续获得三列。我该如何解决?第二个问题:有没有比awk更好的选择?
您可以取消设置记录分隔符以单独读取每个块,如下所示:
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
$ awk -F'[]=():[:space:][]+' -v RS= '{print , , (NF==8?" " :"")}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
最后的三元处理两个不同数量的字段(7 或 8,取决于 "Affected" 或 "not Affected")。如果有8个字段,那么在space之后打印第7个,否则什么都不打印。
为了获得更整齐的格式输出,您可以使用 printf
而不是 print
:
$ awk -F'[]=():[:space:][]+' -v RS= '{printf "%-12s%10s %s%s%s", , , , (NF==8?" " :""), ORS}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
格式说明符规定了每个字段的宽度。 -
导致内容左对齐。 ORS
是输出记录分隔符,在您的平台上默认为换行符。
就列对齐而言,这取决于您要查找的是人类可读还是机器可读的内容。如果您想将此数据导入电子表格,也许您可以使用制表符 \t
(例如)分隔每一列,这可以通过将 -v OFS='\t'
添加到我的第一个版本来完成回答。
您需要将该部分作为一条记录来阅读,您可以在 GAWK 中使用 RS=
(无)来完成此操作。这会将块读取为记录。
awk -vRS= -F"[)(=\n]+" '{print }' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
还有一些awk
输入
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
Affected
2. result = www.addr.com (2.3.4.5)
not Affected
输出
$ awk 's{print [=11=]}s=/^[0-9]+\./{ gsub(/[()]/,"");printf ("%s %s", ,);next}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected
--编辑--修改输入
$ cat file
1. result = 1.2.3.4 (1.2.3.4)
info: [Affected]
2. result = www.addr.com (2.3.4.5)
info: [not Affected]
输出
$ awk '{gsub(/[()\[\]]/,"")}s{="";print [=13=]}s=/^[0-9]+\./{printf ("%s %s", ,);next}' file
1.2.3.4 1.2.3.4 Affected
www.addr.com 2.3.4.5 not Affected