我使用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-string
与s/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 -rn
或sed -r
。
整个搜索和替换命令(“s / … / … / …”)是可选的。 如果使用搜索和替换,为了速度和已经匹配$ matchRe,我们使用尽可能快的$ searchRe值。 字符不需要重新验证,而对于模式的固定长度部分。{$ len}。
没有找到的返回值是$ notFoundExit。
/$matchRe/{s/$searchRe/$replacement/$options; Q}; q$notFoundExit
出于以下原因:
改变Q命令的情况会根据退出何时发生而改变行为。 涉及将布尔逻辑应用于多行输入的行为需要更复杂的解决方案。