2017-08-09 107 views
2

我努力根据所需的输出格式化文件,使用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

回答

8

考虑到你的实际文件是相同的,如图样品INPUT_FILE:

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

这是完美的。清洁和简单。 :) –

+0

谢谢:)很高兴它帮助你。 – RavinderSingh13

2

输入

[[email protected] tmp]$ cat file 
address="192.168.1.1" 
portid="443" 
portid="2000" 
address="192.168.1.2" 
portid="443" 
portid="2000" 

输出

[[email protected] 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" 
+0

谢谢Akshay,这当然看起来不错!拯救了我的一天! :) –

+1

你应该在某个时候接受答案......这是有礼貌的事情。我也认为这应该是一个awk解决方案。在这里有意义。 – stevesliva

+0

对不起史蒂夫我是新来的,不知道我必须这样做。刚刚这样做,谢谢你。 :) –

1

Sed回答。必须小心使用搁置空间。

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

说明:

  • sed -n - 保存在货舱空间
  • /portid/{...}的地址线 - - 每行匹配,只有当明确告知打印
  • /addr/h打印portid,请这样做:
    • x得到保持空间的地址线,把端口ID行保留空间,而不是
    • G的端口ID行追加到地址线
    • s/\nportid/portid/ - 在端口ID行的开始删除换行符
    • p打印的组合线
    • s/portid.*//条的端口ID的东西背部离开组合线
    • h保存在保持空间中的地址线再次
  • 当然,如果输入的是真的这个简单,你可以凝聚我曾经addrportid只是apsed够神秘的地方。

输出:

 
$ sed -n -e '/addr/h;/portid/{x;G;s/\nportid/portid/;p;s/portid.*//;h}' addr.txt 
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

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 
+2

或许'sed'/^address/h;//d;G;s/\(.*\)\n\(.*\)/\2\1/'文件'可能不太忙。 – potong