匹配模式,插入模式,直到下一个匹配

时间:2017-08-09 09:17:26

标签: linux bash awk sed

我正在努力使用bash工具根据所需的输出格式化文件。这是一个示例:

address="192.168.1.1"
portid="443"
portid="2000"
address="192.168.1.2"
portid="443"
portid="2000"

本质上,我想要实现的是搜索模式(在这种情况下,整个IP地址行),并将其添加到每个后续行,直到下一个匹配(在下一个IP地址之前)。所需的输出是:

address="192.168.1.1"portid="443"
address="192.168.1.1"portid="2000"
address="192.168.1.2"portid="443"
address="192.168.1.2"portid="2000"

如何使用grepawksed实现此目标?

3 个答案:

答案 0 :(得分:10)

考虑您的实际文件与示例Input_file相同:

awk '/address/{val=$0;next} {print val $0}'  Input_file

答案 1 :(得分:2)

<强> 输入

[akshay@localhost tmp]$ cat file
address="192.168.1.1"
portid="443"
portid="2000"
address="192.168.1.2"
portid="443"
portid="2000"

<强> 输出

[akshay@localhost tmp]$ awk '/portid/{print a $0; next}/address/{a=$0}' file
address="192.168.1.1"portid="443"
address="192.168.1.1"portid="2000"
address="192.168.1.2"portid="443"
address="192.168.1.2"portid="2000"

答案 2 :(得分:2)

<强> 1。 SED

sed -n 's/address/&/;Ta;h;d;:a;G;s/\(.*\)\n\(.*\)/\2\1/;p' file

不可否认,它比awkperl更加模糊,这在这里更有意义,而且其代码几乎是不言自明的。

s/address/&/;           test (substitute with self) for address
Ta;                     if false, got to label a
h;                      (if true) put the line in the hold buffer
d;                      delete the line from the pattern space
:a;                     set the label a
G;                      append the hold buffer to the pattern space (current line)
s/\(.*\)\n\(.*\)/\2\1/  swap around the newline, so the hold buffer contents
                        are actually prepended to the current line
p                       print the pattern space

更新: potong的建议更短,更容易理解:

sed '/^address/h;//d;G;s/\(.*\)\n\(.*\)/\2\1/' file

<强> 2。 AWK

awk '/address/{a=$0} /portid/{print a$0}' file

第3。 perl的

perl -lane '$a=$_ if /address/;print $a.$_ if /portid/' file