Linux 匹配图案,插入图案,直到下一个匹配为止
我正在努力使用Linux 匹配图案,插入图案,直到下一个匹配为止,linux,bash,awk,sed,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
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"
如何使用grep
、awk
或sed
实现这一点?输入
输出
考虑到您的实际文件与所示的示例输入文件相同:
awk '/address/{val=$0;next} {print val $0}' Input_file
我回答。必须小心使用货舱空间
sed-n-e'/addr/h/portid/{x;G;s/\nportid/portid/;p;s/portid.*/;h;}'
[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-n
-将addr行保存在保留空间中/addr/h
-在匹配portid的每一行上,执行以下操作:/portid/{…}
从保持空间获取addr行,将portid行放在保持空间中x
将portid行追加到addr行G
-删除portid行开头的换行符s/\nportid/portid/
打印组合行p
将portid内容从组合行中剥离出来s/portid.*/
再次将addr行保存在保留空间中h
- 当然,如果输入真的这么简单,您可以将我使用
或addr
的地方压缩为portid
和a
,但是p
已经够神秘的了sed
1。sed
sed -n 's/address/&/;Ta;h;d;:a;G;s/\(.*\)\n\(.*\)/\2\1/;p' file
诚然,它比awk
或perl
更加晦涩难懂,这在这里更有意义,其代码几乎是不言自明的
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
更新:的建议既简短又易于遵循:
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
谢谢Akshay,这看起来很合适!救了我一天!:)你应该在某个时候接受答案。。。这是礼貌的做法。我还认为这应该是一个
awk
解决方案。这里有道理。对不起,史蒂夫,我是新来的,不知道我必须这么做。我刚刚做到了,谢谢你。:)这太完美了。简洁明了。:)谢谢:)很高兴它帮助了你。也许是sed'/^address/h//DGs/\(.*)\n\(.*)/\2\1/'文件
可能不太忙。