简体   繁体   English

匹配两行,替换为三行

[英]Match two lines, replace with three lines

I need to use sed to replace every matching two-line pattern with a three line pattern. 我需要使用sed每个匹配的两线模式替换为三线模式。 Here's my input file ( tempfile.txt ). 这是我的输入文件( tempfile.txt )。

lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

Basically, if a client-hostname "HOSTNAME"; 基本上,如果client-hostname "HOSTNAME"; is missing, then it should be replaced with a tab and then a newline . 缺少,则应先使用tab ,然后再使用newline替换它。

My attempt: sed 'N; /hardware.*}/d; P; D' tempfile.txt 我的尝试: sed 'N; /hardware.*}/d; P; D' tempfile.txt sed 'N; /hardware.*}/d; P; D' tempfile.txt

The result is: 结果是:

lease 192.168.6.100 {
  binding state free;
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

This is my desired output. 这是我想要的输出。

lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
  <tab>
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;
  hardware ethernet 00:e0:4c:68:00:96;
  <tab>
}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

So as you can see, there are consistently three lines between the curlies. 正如您所看到的,在小卷发之间始终有三条线。 That's what I'm aiming for. 这就是我的目标。

This does the trick (piping to cat -A to show non-printable characters): 这可以解决问题(将管道打到cat -A以显示不可打印的字符):

$ sed -r 'N;s/^([[:space:]]*hardware.*)(\n})$/\1\n\t\2/;t;P;D' infile | cat -A
lease 192.168.6.100 {$
  binding state free;$
  hardware ethernet 00:e0:4c:68:00:96;$
^I$
}$
lease 192.168.6.100 {$
  binding state active;$
  hardware ethernet 00:e0:4c:68:00:96;$
  client-hostname "andrew-H81M-S2PH";$
}$
lease 192.168.6.100 {$
  binding state free;$
  hardware ethernet 00:e0:4c:68:00:96;$
^I$
}$
lease 192.168.6.100 {$
  binding state active;$
  hardware ethernet 00:e0:4c:68:00:96;$
  client-hostname "andrew-H81M-S2PH";$
}$

Instead of deleting matches, this captures the two lines supposed to surround the empty line and replaces with the newline and tab between. 而不是删除匹配项,而是捕获应该包围空行的两行,并用换行符和之间的制表符代替。 I've also added a few anchors for safer matching. 我还添加了一些锚点以实现更安全的匹配。

There is a bit of trickery involved because the pattern space contains two newlines after a substitution, but P;D prints only the first line and the starts a new cycle, which leads to unwanted newlines also after lines containing client-hostname . 涉及一些技巧,因为模式空间在替换后包含两个换行符,但是P;D仅打印第一行并开始一个新循环,这也会在包含client-hostname行之后导致不需要的换行符。

Explained in more detail: 详细解释:

N       # Append next line to pattern space

# If the hostname is missing, insert a newline and a tab
s/^([[:space:]]*hardware.*)(\n})$/\1\n\t\2/

t      # If we did the substitution, jump to end (prints complete pattern space)
P      # Print first line in pattern space
D      # Delete first line in pattern space - starts new cycle

I took the liberty to add another curly ... 我冒昧地增加了另一个卷曲...

sed 'N; s/hardware.*}/\t\n}/; P; D' andy
lease 192.168.6.100 {
  binding state free;

}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}
lease 192.168.6.100 {
  binding state free;

}
lease 192.168.6.100 {
  binding state active;
  hardware ethernet 00:e0:4c:68:00:96;
  client-hostname "andrew-H81M-S2PH";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM