Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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"
share|improve this question
    
What OS/version of diff are you working with? –  Mat Sep 4 '12 at 10:09
    
Ubuntu 12.04, diff (GNU diffutils) 3.2 –  l0b0 Sep 4 '12 at 10:44

2 Answers 2

up vote 4 down vote accepted

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.
share|improve this answer
    
the man page for GNU diff 3.2 says only: -N, --new-file treat absent files as empty –  cas Sep 4 '12 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. –  Mat Sep 4 '12 at 11:08

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)

share|improve this answer
    
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 –  cas Sep 4 '12 at 11:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.