我有如下所示的命令输出行。
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