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"
-
What OS/version of diff are you working with?Mat– Mat2012年09月04日 10:09:24 +00:00Commented Sep 4, 2012 at 10:09
-
Ubuntu 12.04, diff (GNU diffutils) 3.2l0b0– l0b02012年09月04日 10:44:05 +00:00Commented Sep 4, 2012 at 10:44
2 Answers 2
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.
-
the man page for GNU diff 3.2 says only:
-N, --new-file
treat absent files as empty
cas– cas2012年09月04日 11:05:57 +00:00Commented 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.Mat– Mat2012年09月04日 11:08:46 +00:00Commented Sep 4, 2012 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)
-
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– cas2012年09月04日 11:02:31 +00:00Commented Sep 4, 2012 at 11:02