17

This command replaces the old string with the new one if the one exists.

sed "s/$OLD/$NEW/g" "$source_filename" > $dest_filename

How can I check if the replacement happened ? (or how many times happened ?)

Lukap
  • 31,523
  • 64
  • 157
  • 244

4 Answers4

9

is not the right tool if you need to count the substitution, will fit better your needs :

awk -v OLD=foo -v NEW=bar '
    ($0 ~ OLD) {gsub(OLD, NEW); count++}1
    END{print count " substitutions occured."}
' "$source_filename"

This latest solution counts only the number of lines substituted. The next snippet counts all substitutions with . This one has the advantage to be clearer than awk and we keep the syntax of sed substitution :

OLD=foo NEW=bar perl -pe '
    $count += s/$ENV{OLD}/$ENV{NEW}/g;
    END{print "$count substitutions occured.\n"}
' "$source_filename"

Edit

Thanks to william who had found the $count += s///g trick to count the number of substitutions (even or not on the same line)

edi9999
  • 19,701
  • 13
  • 88
  • 127
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • 2
    did you tried this ? when I run this on my file it prints the whole file in the console, I just want to count how many times the 'foo' is replaced with 'bar' – Lukap Mar 15 '13 at 13:11
  • `sed` print to STDOUT (terminal) too by default. Remove the number `1` if you don't want to print, but that makes no sense to substitute and not printing and redirecting to a new file ! – Gilles Quénot Mar 15 '13 at 13:20
  • 2
    I think OP also states `how many times happened`. Not just in how many lines but how many substitutions made. Both awk and perl answer only count # of lines substituted. – anubhava Mar 15 '13 at 13:22
  • 2
    In perl try `$count += s/$ENV{OLD}/$ENV{NEW}/g;` (tested in 5.10) – William Mar 15 '13 at 14:06
  • Removed forgotten `&& $count++` – Gilles Quénot Mar 15 '13 at 17:31
  • `sed` can actually be used right for what the OP wants, and this question is a [duplicate](http://stackoverflow.com/questions/12144158/how-to-check-if-sed-has-changed-a-file) anyway. – Dan Dascalescu May 10 '15 at 00:16
  • you could have used the `count +=` with your awk version too... `($0 ~ OLD){a=gsub(OLD,NEW); count+=a}1` – wmorrison365 Jun 22 '15 at 10:11
1

This awk should count the total number of substitutions instead of the number of lines where substitutions took place:

awk 'END{print t, "substitutions"} {t+=gsub(old,new)}1' old="foo" new="bar" file
Scrutinizer
  • 9,608
  • 1
  • 21
  • 22
0

If it is free for you to choose other tool, like awk, (as @sputnick suggested), go with other tools. Awk could count how many times the pattern matched.

sed itself cannot count replacement, particularly if you use /g flag. however if you want to stick to sed and know the replacement times there is possibilities:

One way is

grep -o 'pattern'|wc -l file && sed 's/pattern/rep/g' oldfile > newfile

you could also do it with tee

cat file|tee >(grep -o 'pattern'|wc -l)|(sed 's/pattern/replace/g' >newfile) 

see this small example:

kent$  cat file
abababababa
aaaaaa
xaxaxa

kent$  cat file|tee >(grep -o 'a'|wc -l)|(sed 's/a/-/g' >newfile)
15

kent$  cat newfile                                               
-b-b-b-b-b-
------
x-x-x-
Kent
  • 189,393
  • 32
  • 233
  • 301
  • Linux 5.16, Debian Bookworm/Sid: The output from wc is piped into sed after the output from tee. If I redirect the output from wc into a third file (>), then the count is separate from newfile. – Paul Feb 04 '23 at 14:22
0

this worked for me.

awk -v s="OLD" -v c="NEW" '{count+=gsub(s,c); }1
END{print count "numbers"}
' opfilename
Birei
  • 35,723
  • 2
  • 77
  • 82
Narayan
  • 48
  • 2
  • A short paragraph or even a sentence or two by way of explanation would have gone a long way into making this a great answer. –  May 10 '15 at 00:34