如何使用 sed 在行前和行后附加字符串

如何使用 sed 在行前和行后附加字符串

我有如下所示的命令输出行。

service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started

我想在仅表示 [Z] 的行前后添加字符串。因此结果可能是这样的:

<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

有人能帮我做这个吗?非常感谢您的帮助。

我尝试了以下方法,但是输出的所有行都发生了改变

sed -i "s/.*/<font color="red">&<\/font>/"

答案1

你可以使用这个:

sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p' file.txt

因为您将在另一个命令的 STDOUT 上使用它,所以使用它作为例如:

some command | sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p'

它基本上有两个部分:

  • /\[Z\]$/ s/^/<font>/将匹配最后一行,然后在行首[Z]添加<font>s/^/<font>/

  • /\[Z\]$/ s/$/<\/font>/[Z]将在行尾匹配,然后</font>使用 在行尾添加/$/<\/font>/

例子 :

$ cat file.txt 
service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started

$ sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p' file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

正如 @glennjackman 指出的那样,您还可以使用分组构造对单个匹配项进行所有替换:

$ sed -n '/\[Z\]$/ { s/^/<font>/; s/$/<\/font>/p }' file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

解决方案如何bash

while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done <file.txt

您可以将其用作:

some command | while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done

这使用与上一个相同的逻辑sed。如果行以[Z]( [[ $line =~ \[Z\]$ ]]) 结尾,则该行将以所需格式打印。

例子 :

$ while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done <file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

答案2

您的尝试已经非常接近了;您需要做的就是将替换的执行范围缩小到[Z]最后包含以下内容的行:

sed -i '/\[Z\]$/ s/.*/<font>&<\/font>/' infile

但是,这里还有另一种awk解决方案:

awk '$4=="[Z]" {printf("%s%s%s\n", "<font>", $0, "</font>"); next} {print}' infile
  • $4=="[Z]":模式;如果当前处理的记录的第4个字段是[Z],则执行以下操作;否则,跳到下一个模式/动作;
  • printf("%s%s%s\n", "<font>", $0, "</font>"):打印<font>当前处理的记录和</font>字符串,后跟换行符;
  • next:跳到下一条记录;
  • print:打印当前处理的记录,后跟换行符;

示例输出:

user@debian ~ % cat infile
service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started
user@debian ~ % awk '$4=="[Z]" {printf("%s%s%s\n", "<font>", $0, "</font>"); next} {print}' infile
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started

答案3

Awk版本。

使用 OP 的示例进行了测试,将其粘贴到同一个文件中两次,因此您可以看到它编辑了包含的两行[Z]和不包含的两行

  $ awk ' {if ($0~/\[Z\]/)  print "<font>"$0"</font>";else print}' testfile.txt                                                                   
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started

要将编辑输出到文件,请使用以下构造:

awk ' {if ($0~/\[Z\]/) print "<font>"$0"</font>";else print}' testfile.txt > /tmp/tmp.txt && cat /tmp/tmp.txt > testfile.txt

相关内容