sed的返回码不匹配

我使用sed在运行时更新我的​​jsonconfiguration文件。 有时,当模式在json文件中不匹配时,仍然退出sed退出码0。

返回0意味着成功完成,但为什么sed返回0,如果它找不到适当的模式并更新文件? 有没有解决方法?

谢谢!

作为@cnicutar评论,一个命令的返回代码意味着如果命令被成功执行。 与您在代码/脚本中实现的逻辑无关。

所以如果你有:

 echo "foo"|sed '/bar/ s/a/b/' 

sed将返回0但如果你写一些语法/表达式错误,或输入/文件不存在,sed不能执行你的请求,sed将返回1。

解决方法

这实际上不是解决方法 。 sed有q命令:(从手册页):

  q [exit-code] 

在这里你可以定义你想要的退出代码。 例如:

配对情况:

 kent$ echo "foo"|sed '/foo/ {s/f/b/;q}' boo kent$ echo $? 0 

无与伦比的案例:

 kent$ echo "trash"|sed '/foo/{s/f/b/;q}; /foo/!{q100}' trash kent$ echo $? 100 

我希望这回答了你的问题。

编辑

我必须补充一点,上面的例子只是用于单行处理。 我不知道你的具体要求。 当你想要exit 1 。 一行无法匹配或整个文件。 如果整个文件不匹配的情况下,你可以考虑awk,甚至在你的文本处理之前做一个grep

这可能适用于你(GNU sed):

 sed '/search-string/{s//replacement-string/;h};${x;/./{x;q0};x;q1}' file 

如果找到search-string ,它将被替换replacement-string替换,并在文件结束sed将退出0返回代码。 如果没有替换发生,返回码将是1

更详细的解释:

在sed中,用户有两个寄存器供他处理:当前行加载到的模式空间(PS)(减去换行)和一个空闲的寄存器,称为保持空间(HS),它最初是空的。

一般的想法是用HS作为标志来表示是否发生替换。 如果HS在文件末尾仍然是空的,则不做任何更改,否则发生更改。

命令/search-string/search-string与PS中的任何内容匹配,并且如果发现包含search-string ,则执行后面大括号中的命令。

首先替换s//replacement-string/ (sed使用最后一个正则表达式即search-string ,如果左侧是空的,所以s//replacement-strings/search-string/replacement-string/ ),然后h命令复制PS并将其放入HS。

sed命令$用于识别文件的最后一行,然后发生。

首先x命令交换两个寄存器,所以HS成为PS,PS成为HS。

然后PS搜索任何字符/./.表示匹配任何字符)记住HS(现在的PS)最初是空的,直到替换发生。 如果条件为真,则再次执行x ,然后执行q0命令,结束所有sed处理,并将返回码设置为0 。 否则,执行x命令并将返回码设置为1

注意,尽管q退出sed处理,但并不妨碍sed按照正常情况重新组装se。

另一种选择:

 sed '/search-string/!ba;s//replacement-string/;h;:a;$!b;p;x;/./Q;Q1' file 

要么:

 sed '/search-string/,${s//replacement-string/;b};$q1' file 

这些答案太复杂了。 编写一些使用grep来查找是否需要替换的东西的shell脚本有什么问题,然后使用sed来替换它?

 grep -q $TARGET_STRING $file if [ $? -eq 0 ] then echo "$file contains the old site" sed -e "s|${TARGET_STRING}|${NEW_STRING}|g" .... fi 

我曾经想要通过在找到匹配项时退出来截断文件(并排除匹配的行)。 当在文件末尾添加行的进程可能会重新运行时,这很方便。 “Q; Q1”不起作用,只是“Q1”而已,如下:

如果sed -i'/ text我想要找到/ Q1'file.txt,然后在文件的末尾插入空行+新行fi只插入没有空行的新行

以下是我们使用sed -rnsed -r

整个搜索和替换命令(“s / … / … / …”)是可选的。 如果使用搜索和替换,为了速度和已经匹配$ matchRe,我们使用尽可能快的$ searchRe值。 字符不需要重新验证,而对于模式的固定长度部分。{$ len}。

没有找到的返回值是$ notFoundExit。

 /$matchRe/{s/$searchRe/$replacement/$options; Q}; q$notFoundExit 

出于以下原因:

  • 没有时间浪费测试匹配和不匹配的情况
  • 没有时间浪费复制到缓冲区或从缓冲区
  • 没有多余的分支
  • 合理的灵活性

改变Q命令的情况会根据退出何时发生而改变行为。 涉及将布尔逻辑应用于多行输入的行为需要更复杂的解决方案。