9

I'm trying to compare files on the root file system with a backup, and I'd like the comparison to work a bit like git or svn diff when a file has been added or removed - That is, display the full file diff. diff unfortunately just prints a No such file or directory message, which is not very useful. I couldn't find an option for this.

The simplest workaround I could find is to parse the diff output and diff -u path <(printf '') or diff -u <(printf '') path depending on which path exists. That's a bit of a kludge - Probably 10 lines of code for what could be a simple diff option.

Another workaround is

diff -u <([ -e "$path1" ] && cat "$path1") <([ -e "$path2" ] && cat "$path2")

, but that loses the file names in the diff.

Based on Craig Sanders's answer and the previous workaround, I ended up with this:

diff -u \
 "$([ -e "$path1" ] && echo "$path1" || echo /dev/null)" \
 "$([ -e "$path2" ] && echo "$path2" || echo /dev/null)"

Edit: Turns out there is an option for it:

-N, --new-file
 treat absent files as empty

In other words:

diff -Nu "$path1" "$path2"
asked Sep 4, 2012 at 9:58
2
  • What OS/version of diff are you working with? Commented Sep 4, 2012 at 10:09
  • Ubuntu 12.04, diff (GNU diffutils) 3.2 Commented Sep 4, 2012 at 10:44

2 Answers 2

12

With at least some versions of GNU diffutils' diff, you can use the -N flag to do that directly (although the documentation appears to say that only works for directory diffs).

$ ls
foo
$ cat foo
foo
$ diff -u foo bar
diff: bar: No such file or directory
$ diff -uN bar foo
--- bar 1970年01月01日 01:00:00.000000000 +0100
+++ foo 2012年09月04日 12:45:34.000000000 +0200
@@ -0,0 +1 @@
+foo
$ diff -uN foo bar
--- foo 2012年09月04日 12:45:34.000000000 +0200
+++ bar 1970年01月01日 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-foo
$ diff -v
diff (GNU diffutils) 2.8.1
Copyright (C) 2002 Free Software Foundation, Inc.
answered Sep 4, 2012 at 10:49
2
  • the man page for GNU diff 3.2 says only: -N, --new-file treat absent files as empty Commented Sep 4, 2012 at 11:05
  • The version I have on hand (2.8.1) says "In directory comparison, if a file is found in only one directory, treat it as present but empty in the other directory.", so that's why I put the disclaimer. Good to know that's now documented for non-directory diffs now. Commented Sep 4, 2012 at 11:08
3

have you tried diff -u /dev/null filename ?

that worked for me when i just tried it.

alternatively:

touch missing
diff -u missing filename
rm missing

Also, if you diff directories (e.g. diff -x /path/to/backup -uN / /path/to/backup) then diff will recursively show full diffs of all files, including missing files. You need the -x, --exclude=PAT option because /path/to/backup is a subdir of /

(thanks to Mat for reminding me of the -N option)

answered Sep 4, 2012 at 10:36
1
  • thanks for the accept but i think Mat's answer is better. diff -N seems to do exactly what you want without stuffing around with tempfiles or /dev/null, and it gives you the recursive two-directory diff that i edited out of my answer because it doesn't work properly without -N Commented Sep 4, 2012 at 11:02

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.