Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 匹配图案,插入图案,直到下一个匹配为止_Linux_Bash_Awk_Sed - Fatal编程技术网

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/h
    -将addr行保存在保留空间中
  • /portid/{…}
    -在匹配portid的每一行上,执行以下操作:
    • x
      从保持空间获取addr行,将portid行放在保持空间中
    • G
      将portid行追加到addr行
    • s/\nportid/portid/
      -删除portid行开头的换行符
    • p
      打印组合行
    • s/portid.*/
      将portid内容从组合行中剥离出来
    • h
      再次将addr行保存在保留空间中
  • 当然,如果输入真的这么简单,您可以将我使用
    addr
    portid
    的地方压缩为
    a
    p
    ,但是
    sed
    已经够神秘的了
输出:

$ 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" $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”
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/'文件
可能不太忙。