0

I have an input file "test.txt" as below -

host = abc.com host = xyz.com
db-host = abc.com db-host = xyz.com

In each line, the value before space is the old value which needs to be replaced by the new value after space recursively in a folder named "test"

"sed" replaces the strings on the fly in 100s of files.

Is there a trick or an alternative way by which I can get a report of the files changed like the absolute path of the file & the exact lines that got changed?

PS - I understand that sed or stream editors don't support this functionality out of the box. I don't want to use versioning as it will be an overkill for this task.

1 Answers1

0

You can easily achieve this with perl:

find -type f -iname '*.txt' -exec perl -i -lape 'if (/.+\s=\s.+\s.+\s=\s.+/) {s/.+\s=\s.+\s(.+\s=\s.+)/\1/; push (@lines, $_);} END {if (@lines) {print STDOUT "\n" . $ARGV . ":"; foreach (@lines){print "$_";}}}' {} \;

Breakdown:

find -type f -iname '*.txt' look for files in the current directory and subdirectories, whose filename ends in .txt

-exec run the following command on each file that gets found

perl -i -lape in place edit files according to the following perl script.

if (/.+\s=\s.+\s.+\s=\s.+/) if the line matches the pattern you gave: xxx = xxx xxx = xxx where x is any character

{s/.+\s=\s.+\s(.+\s=\s.+)/\1/; search and replace, keeping only the second part of the line

push (@lines, $_);} add the edited line to an array

END after all lines in the file have been processed, do the following

if (@lines) only do this if there were any modified lines in the file

{print STDOUT "\n" . $ARGV . ":"; print a blank line, then the filename followed by a semicolon

foreach (@lines){print "$_";}}} print each line that was modifies in that file

{} \; this is a placeholder for the find result

simlev
  • 919
  • 2
  • 12
  • 26