Tomasz Stanik
Tomasz Stanik

Reputation: 73

How to force sed to print what it does with my file?

How to force sed to print what it does with my file?

My text01.txt file:

aaa
bbb
ccc
ddd
c
ee

My code:

sed -i 's/c/X/g' ./text01.txt

I want to get in terminal something like this:

sed: line 3 change ccc to XXX
sed: line 5 change c to X

Upvotes: 2

Views: 317

Answers (3)

potong
potong

Reputation: 58473

This might work for you (GNU sed):

sed -i -e 'h;/c/!b;s//X/g;H;x;s/\n/ to /;s/^/sed: changed /w/dev/stdout' -e 'x' file

This makes a copy of each line in the hold space (HS) and if the substitution pattern does not match, no further action takes place. Otherwise, the substitution is made on the line in the pattern space (PS) and this is appended to the HS. Focus is then changed to the HS and format of before and after effected. The formated line is then written out to the standard output i.e. the terminal and finally focus is reverted to the PS so that the substituted line is included in the original updated file.

Upvotes: 0

Benjamin W.
Benjamin W.

Reputation: 52316

This comes pretty close to your requirement:

$ paste <(cat -n text01.txt) <(sed 's/c/X/g' ./text01.txt)
     1  aaa aaa
     2  bbb bbb
     3  ccc XXX
     4  ddd ddd
     5  c   X
     6  ee  ee

cat -n prepends line numbers, and the paste command with process substitution prints the file and the sed output next to each other.

Or, more elaborate, with awk:

awk '{ getline mod_line < ARGV[2]
       if ($0 != mod_line) {
           printf "sed line %d change %s to %s\n", NR, $0, mod_line }
}' text01.txt <(sed 's/c/X/g' text01.txt)

This reads, for each line of text01.txt, the corresponding line as modified by sed. If they are different, the line number and both lines get printed:

sed line 3 change ccc to XXX
sed line 5 change c to X

plus an awk warning because it tries to close an anonymous pipe – this can be suppressed by redirecting stderr, i.e., appending 2> /dev/null to the command.

The closest thing to sed "built-in" debugging is the l command, which prints the current content of the pattern space. If you'd like to go all in, there are proper debuggers, for example sedsed.

Upvotes: 0

Kent
Kent

Reputation: 195179

 sed -i"bak" 's/c/X/g' text01.txt && diff text01.txt text01.txtbak

will give you a diff summary. like:

3c3
< XXX
---
> ccc
5c5
< X
---
> c

You can read diff man page, to adjust the diff output, e.g. with -c/-u/-y... options as you like.

If you want to get exactly same format you described, you can do some work on diff output as well.

Upvotes: 1

Related Questions