1

I'm writing now bash script for Ubuntu. I have a lot of sed statements that replace and change some text in files.

My question is: How can i know if the change was performed or not.

For example, I have this statement:

sed -i "s;#net.ipv4.ip_forward=1;net.ipv4.ip_forward=1;" /etc/sysctl.conf

Was a change to the file actually made?

tripleee
  • 175,061
  • 34
  • 275
  • 318
Ahmed M. Abed
  • 599
  • 3
  • 9
  • 22
  • @tripleee yes, but i need to know the result of the command. if the changes done or no – Ahmed M. Abed Apr 17 '16 at 06:45
  • `sed` will not tell you explicitly whether the file was changed; maybe use an Awk or Perl or Python one-liner instead if you need this level of control. – tripleee Apr 17 '16 at 06:46
  • I made an edit to hopefully clarify your question. Please review. – tripleee Apr 17 '16 at 07:01
  • Try this : `echo "foo" | sed 's/bar//;t quit;q1;:quit q';echo $?`. Exit status will be 0 if substitute succeeded, 1 if it failed. – SLePort Apr 17 '16 at 07:29
  • @tripleee sed can tell if change was performed combining simple `t`est and `b`ranch commands. Example in above comment. – SLePort Apr 17 '16 at 07:53
  • @Kenavoz The exit code argument to `q` is not portable. See the duplicate anyway. – tripleee Apr 17 '16 at 08:00
  • @triplee I know but with GNU sed, it could have been a simple solution. – SLePort Apr 17 '16 at 08:24
  • @Kenavoz You are also assuming the replacement will be on the last line of the file. If it's not, I don't know if it could be done. The `w` solution in the duplicate looks more probising IMHO. – tripleee Apr 17 '16 at 09:34
  • @tripleee You're right. It's just a lightweight solution for a one (or more) simple substitutions. It's based on the OP sample, not for complex sed commands. – SLePort Apr 17 '16 at 09:47

3 Answers3

1

With GNU Awk,

if gawk --inplace '/^#net\.ipv4\.ip_forward=1$/ { sub("#",""); s=1 }
    1
    END { exit 1-s }' /etc/sysctl.conf
then
    echo "Success"
else
    echo "No change"
fi

This fails to correctly distinguish between no change and a system error (permission denied, file not found, etc). You'll perhaps want to check for those conditions before running Awk; or maybe explicitly examine $? and scream if it's not 1 in the failure branch.

Also notice that the regex is more strict than in your example. If you genuinely want a change anywhere in a line with other text in it, too, you'll need to adapt.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

You could use cmp to compare the old and new versions of the file. In fact, that is probably the most reliable way to determine if sed has done something.

Note that you cannot rely on the sed exit status to determine whether it made any changes. All the exist status will tell you is whether or not the sed run "succeeded".

Even if it did ... the exit status is not documented in the man or info pages for GNU sed. The behavior is "an implementation detail", and might change.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
-2

You can check the result of the command using $? shell variable.

You can also change the return status of sed command if no match is found. Related link: Return code of sed for no match

Community
  • 1
  • 1
randominstanceOfLivingThing
  • 16,873
  • 13
  • 49
  • 72
  • 1
    This doesn't reveal whether any change was written, though. Most scripts don't need to examine `$?` explicitly; `if` and `while` etc do this behind the scene for you. – tripleee Apr 17 '16 at 06:50