如何检查sed是否更改了文件

我试图find一个聪明的方法来确定文件传递给sed是否被成功修改。

基本上,我想知道文件是否已经改变,而不必看文件修改date。

我需要这个的原因是因为如果sed成功地replace了一个模式,我需要做一些额外的工作。

我目前有:

grep -q $pattern $filename if [ $? -eq 0 ] then sed -is:$pattern:$new_pattern: $filename # DO SOME OTHER STUFF HERE else # DO SOME OTHER STUFF HERE fi 

上面的代码是有点贵,我希望能够在这里使用一些黑客。

Solutions Collecting From Web of "如何检查sed是否更改了文件"

你可以用awk代替:

 awk "/$pattern/"' { gsub( "'"$pattern"'", "'"$repl"'" ); t=1 } 1; END{ exit( !t )}' 

我忽略了-i功能:你可以使用shell做必要的重定向。

晚会有点晚,但为了别人的利益,我发现“w”的标志正是我所期待的。

 sed -i "s/$pattern/$new_pattern/w changelog.txt" "$filename" if [ -s changelog.txt ]; then # CHANGES MADE, DO SOME STUFF HERE else # NO CHANGES MADE, DO SOME OTHER STUFF HERE fi 

changelog.txt将包含它自己的行上的每个更改(即更改后的文本)。 如果没有更改,则changelog.txt将为零字节。

一个真正有用的sed资源(以及我在哪里找到这个信息)是http://www.grymoire.com/Unix/Sed.html

我相信你可能会发现这些GNU sed扩展有用

 t label If as/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script. 

 q [exit-code] Immediately quit the sed script without processing any more input, except that if auto-print is not disabled the current pattern space will be printed. The exit code argument is a GNU extension. 

看来你正在寻找什么。

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

 sed -i.bak '/'"$old_pattern"'/{s//'"$new_pattern"'/;h};${x;/./{x;q1};x}' file || echo changed 

说明:

  • 如果模式空间(PS)包含old pattern ,则将其替换为new pattern ,并将PS复制到保持空间(HS) )。
  • ${x;/./{x;q1};x}在遇到最后一行时,交换到HS并测试它是否存在任何字符串。 如果在HS中发现一个字符串(即发生了替换),则交换回原始PS并使用1的退出码退出,否则返回原始PS并退出,退出代码为0 (默认值) 。

您可以使用sed输出来区分原始文件,看看它是否发生了变化:

 sed -i.bak s:$pattern:$new_pattern: "$filename" if ! diff "$filename" "$filename.bak" &> /dev/null; then echo "changed" else echo "not changed" fi rm "$filename.bak" 

我知道这是一个老问题,使用awk而不是sed也许是最好的想法,但是如果想坚持sed,一个想法就是使用-w标志。 w标志的文件参数只包含匹配的行。 所以,我们只需要检查它是不是空的。