[英]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.