Kerim Kerim - 4 months ago 12
Bash Question

diff line-format: Show delete, new, and changed lines?

backup.txt

user1:password:17002:0:99:7:::
user2:password:17003:0:99:7:::
user3:password:17004:0:99:7:::


"main.txt" is same with "backup.txt". If I rename "user1", add a new user, and remove "user2" in "main.txt". "main.txt" seems like:

username1:password:17002:0:99:7:::
user3:password:17004:0:99:7:::
newUser:password:17005:0:99:7:::


after that I use following command for compare two files:

diff --unchanged-line-format="" --old-line-format=":%dn: %L" --new-line-format=":%dn: %L" backup.txt main.txt


...with the actual output:

:1: user1:password:17002:0:99:7:::
:2: user2:password:17003:0:99:7:::
:1: username1:password:17002:0:99:7:::
:3: newUser:password:17005:0:99:7:::


However, my intended output was:

:1c: user1:password:17002:0:99:7:::
:2d: user2:password:17003:0:99:7:::
:1c: username1:password:17002:0:99:7:::
:3a: newUser:password:17005:0:99:7:::


like this. These characters are enable for default "diff" command using. How can I enable these characters for line formatting. Is it possible?

Answer

The LTYPEs offered by both BSD and GNU diff are "old", "new", and "unchanged". You thus can't distinguish between "new" and "changed".

That said, to get some distinctions in your format strings, you need to fill them out correctly. In %dn, both the d and the n are consumed (the former specifying a decimal value, the n specifying that it refer to the line number, or the number of lines modified, depending on context). Thus, if you want any extra characters (such as a c, d or a), you need to add those characters after that substitution has complete.

# declaring functions to allow testing without creating files on-disk
backup () { printf '%s\n' user1:password:17002:0:99:7::: user2:password:17002:0:99:7::: user3:password:17002:0:99:7:::; }
main () { printf '%s\n' username1:password:17002:0:99:7::: user3:password:17004:0:99:7::: newUser:password:17005:0:99:7:::; }

diff \
  --unchanged-line-format=":%dnu: %L" \
  --old-line-format=":%dnd: %L" \
  --new-line-format=":%dnn: %L" \
  <(backup) <(main)