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

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

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

实质上,我试图实现的是search一个模式(在这种情况下,整个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

考虑到你的实际文件是相同的显示样本Input_file:

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

输入

 [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" 

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 

Sed回答。 必须小心使用保持空间。

sed -n -e '/addr/h;/portid/{x;G;s/\nportid/portid/;p;s/portid.*//;h;}'

说明:

  • sed -n – 只有在明确告知打印时才打印
  • /addr/h – 将地址线保存在保存空间中
  • /portid/{...} – 每行匹配portid,执行以下操作:
    • x从保留空间中获取addr行,将portid行放入保留空间中
    • G将portid行添加到addr行
    • s/\nportid/portid/ – 删除portid行开始处的换行符
    • p打印组合的线
    • s/portid.*//将portid的东西从合并的行中删除
    • h再次将地址线保存在保留空间中
  • 当然,如果输入真的很简单,可以将我使用addrportid的地方portidap但是sed足够了。

输出:

 $ sed -n -e'/addr/h;/portid/{x;G;s/\nportid/portid/;p;s/portid.*//h}'addr.txt 
地址= “192.168.1.1” 端口ID = “443”
地址= “192.168.1.1” 端口ID = “2000”
地址= “192.168.1.2” 端口ID = “443”
地址= “192.168.1.2” 端口ID = “2000”