Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.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
Bash sed查找替换或添加(如果未找到任何内容)_Bash_Replace_Sed - Fatal编程技术网

Bash sed查找替换或添加(如果未找到任何内容)

Bash sed查找替换或添加(如果未找到任何内容),bash,replace,sed,Bash,Replace,Sed,我的config.txt文件中有以下内容 some text firmware_version 12.3 some more text ... sed-i的/^firmware\u version.*/firmware\u version 12.4/'/config.txt命令将替换固件版本,但 我希望能够做到的是,即使sed没有找到“firmware\u version.*”的行匹配项,它仍然会添加新的替换项 换句话说,如果我的config.txt文件包含以下内容: some text so

我的config.txt文件中有以下内容

some text
firmware_version 12.3
some more text ...
sed-i的/^firmware\u version.*/firmware\u version 12.4/'/config.txt
命令将替换固件版本,但 我希望能够做到的是,即使
sed
没有找到
“firmware\u version.*”
的行匹配项,它仍然会添加新的替换项

换句话说,如果我的config.txt文件包含以下内容:

some text
some more text ...
我还是希望最终的结果是

some text
firmware_version 12.4
some more text ...
我只是想想出一个通用的单行命令

谢谢

awk解决方案:

awk '/some text/,/some more text/{if (index($0, "firmware_version")) {$0="firmware_version 12.4"; p=1; next}} !p{sub(/$/, "\nfirmware_version 12.4"); p=1} 1' file
这将产生以下输出:

some text
firmware_version 12.4
some more text ...
对于两个输入文件:

some text
firmware_version 12.3
some more text ...
还有这个:

some text
some more text ...

对于非空文件,这是有效的。不过,这是另一种模式。如果“固件版本”出现在“某些文本”和“更多文本”之间,则将其删除。当您遇到“更多文本”时,请插入固件版本。我将编辑命令放入一个名为(非原创)
sed.script的文件中已经够棘手的了:

/some text/,/some more text/{
/firmware_version .*/d
/some more text/i\
firmware_version 12.4
}
然后,给定
config-1.txt

some text
firmware_version 12.3
some more text
some text
some more text
config-2.txt

some text
firmware_version 12.3
some more text
some text
some more text
您可以按如下方式运行脚本:

sed -f sed.script config-1.txt
它为两个输入产生相同的输出:

some text
firmware_version 12.4
some more text
如果输入文件为空,我认为最好单独处理。此shell脚本片段将新文件写入标准输出:

if [ -s ${config_file} ]
then sed -f sed.script ${config_file}
else echo "firmware_version 12.4"
fi
如果要覆盖原始文件且您的
sed
支持
-i.bak
,则:

if [ -s ${config_file} ]
then sed -i.bak -f sed.script       ${config_file}
else echo "firmware_version 12.4" > ${config_file}
fi

谢谢你的回复

我真的在寻找一个更简单的解决方案,我希望
sed
在搜索的文本不匹配时返回一个不同的退出状态,然后我可以决定下一步做什么

有一些关于如何使
sed
在不符合条件时返回特定代码的说明,但我无法使其工作,手册也没有提及任何内容(或者我可能遗漏了一些内容)

经过进一步研究,我发现这不是一个很好的解决方案,而是一个可以接受的解决方案

grep -q '^firmware_version .*' /config.txt && sed -i 's/^firmware_version .*/firmware_version 12.4/' /config.txt || echo 'firmware_version 12.4' >> /config.txt

因此,如果grep找到了匹配项,那么我们运行
sed
命令,否则我们将
echo
将'firmware\u version 12.4'文本转换为config.txt

是否应检测到'some text'或'some more text'作为匹配项,而中间没有'firmware\u version'?或者,如果找不到“固件版本”,那么“固件版本”是否可以在末尾执行?发现两行之间缺少固件版本可能比在最后添加固件版本更难,尽管这两行都不是完全直接的。“some text”和“some more text”之间除了“firmware\u version”之外还有其他行吗?“firmware\u version”可以在没有找到的情况下结束,并且配置文件也可以完全为空,因此配置文件中可能没有任何内容,如果执行该命令,仍然应该添加“firmware\u version”。