Reshape text

INPUT · Slides

Show the difference (`diff`)

01 / 07

The tool that answers "what changed?"

The chapter finishes with diff, which shows the difference between two files.

You reach for it in moments like these.

  • You edited a configuration file. What did you change again?
  • The copy from when it worked, and the one you have now. What differs?
  • Two lists of names. Who is only on one of them?

Comparing by eye is hard work and you miss things. diff tells you only what differs.

02 / 07

Read it by the - and +

Let us compare a.txt and b.txt.

~ $ diff a.txt b.txt--- a.txt+++ b.txt@@ -1,3 +1,3 @@ apple-orange+grape banana

Read it like this.

Start of lineMeaning
(a space)in both (unchanged)
-only in the first (removed)
+only in the second (added)

So it is saying "orange became grape".

The --- a.txt and +++ b.txt tell you which one is - and which is +. - is the left, + is the right.

03 / 07

@@ says where you are

That @@ -1,3 +1,3 @@ line is curious. It tells you which part of the file this is about.

@@ -1,3 +1,3 @@     ^     ^   in the  in the   first   second   three lines from line 1

In a big file it pulls out only the differing parts to show you, and the @@ line is what tells you roughly which lines they came from.

This layout is called unified format, and git diff and software patches use exactly the same thing.

Learning to read it here pays off for a long time, because when you ask someone to look over a change to a program, this is always the form you show it in.

04 / 07

When they match it says nothing

a.txt and c.txt have the same contents.

~ $ diff a.txt c.txt~ $

Nothing comes out. As with grep and find, "nothing to say" means "nothing wrong".

When you want it said out loud, add -s.

~ $ diff -s a.txt c.txtFiles a.txt and c.txt are identical

The other way round, when you only want to know whether they differ and not how, there is -q.

~ $ diff -q a.txt b.txtFiles a.txt and b.txt differ

Handy for big files, when "same or different" is all you need.

05 / 07

You can judge by the exit status

diff also tells you the answer through the exit status.

StatusMeaning
0the same
1different

You can see the last exit status with $?.

diff a.txt b.txt; echo "code=$?"

What makes this useful is that a program can use it. A machine can decide, rather than a person looking.

if diff -q a.txt b.txt > /dev/null; then  echo sameelse  echo differentfi

That if gets covered in chapter 11. For now, know that diff answers with a number too, which is how you build something that watches for you.

06 / 07

It finds the differences you cannot see

diff also finds differences you cannot see.

d.txt is almost identical to a.txt, except the first line has two spaces at the end.

~ $ diff a.txt d.txt@@ -1,3 +1,3 @@-apple+apple orange banana

-apple and +apple. They look the same, yet it reported a difference, because trailing spaces are invisible.

That sort of thing causes the "it looks the same but it does not work" kind of fault, so diff telling you is a kindness.

When you want to ignore spacing, add -b.

diff -b a.txt d.txt    # nothing comes out

07 / 07

Now have a go

Five files.

  • a.txtapple, orange, banana
  • b.txtapple, grape, banana (the middle differs)
  • c.txtthe same as a.txt
  • d.txt — looks the same as a.txt, but the first line has trailing spaces
  • e.txta.txt with peach added

Which two you compare changes the result, so work through them.

The order in diff A B matters. Swap them and the - and + swap too. Decide to always write "before, then after" and you will not get confused.