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
  • 30,736
  • 61
  • 153
  • 243

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
  • 18,115
  • 12
  • 85
  • 125
Gilles Quenot
  • 154,891
  • 35
  • 213
  • 206
  • 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 Quenot 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
  • POST edited accordingly william, thanks – Gilles Quenot Mar 15 '13 at 14:17
  • Removed forgotten `&& $count++` – Gilles Quenot 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
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
  • 181,427
  • 30
  • 222
  • 283
0

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,228
  • 1
  • 20
  • 22
0

this worked for me.

awk -v s="OLD" -v c="NEW" '{count+=gsub(s,c); }1
END{print count "numbers"}
' opfilename
Birei
  • 34,778
  • 2
  • 71
  • 80
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