我试图找到一种聪明的方式,计算出,如果传递给sed的文件已经成功或没有改变。
基本上,我想知道,如果该文件已被更改或不,而不看文件的修改日期。
为什么我需要这个的原因是因为我需要做一些额外的东西,如果战略经济对话成功替代的模式。
我目前有:
grep -q $pattern $filename
if [ $? -eq 0 ]
then
sed -i s:$pattern:$new_pattern: $filename
# DO SOME OTHER STUFF HERE
else
# DO SOME OTHER STUFF HERE
fi
上面的代码是有点贵,我很想能够在这里使用一些黑客。
您可以使用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 a s/// 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
说明:
-
/'"$old_pattern"'/{s//'"$new_pattern"'/;h}
如果模式空间(PS)中包含的old pattern
,通过更换new pattern
并复制PS到保留空间(HS )。 -
${x;/./{x;q1};x}
在遇到的最后一行,交换到HS,并测试其任何串的存在。 如果字符串是在HS中发现(即,置换已经发生)交换回原来的PS和出口使用的退出代码1
,否则交换回原来的PS和出口与退出代码0
(缺省值) 。
你可以diff的原始文件与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标志仅包含一个匹配的行。 所以,我们只需要检查它不是空的。