How to check if the sed command replaced some stri

2019-04-19 08:26发布

问题:

This question already has an answer here:

  • How to check if sed has changed a file 6 answers

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 ?)

回答1:

sed is not the right tool if you need to count the substitution, awk 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 perl. 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)



回答2:

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-


回答3:

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


回答4:

this worked for me.

awk -v s="OLD" -v c="NEW" '{count+=gsub(s,c); }1
END{print count "numbers"}
' opfilename