I have 2 sorted files produced by

xxx>find /store -type f -print | sort > /tmp/invent.txt
xxx>find /fbkup -type f -print | sort > /tmp/backup.txt

I want from diff a file name list of files missing in /store which are still on /backup, without any < > annotations, just one output file containing exactly the same records from /tmp/backup for which there was no match on /tmp/invent.txt.

xxx>diff -??? /tmp/invent.txt /tmp/invent.txt | xargs ...

Diff your files, then use awk to find the lines you want (/^<), strip the leading bit (gsub(/^</,"")), and print the matched line.

diff file1 file2 | awk '/^</ {gsub(/^</,""); print}'

So if you want a one liner you could even do something like this.

diff <(cd /store ; find . -type f -print | sort) \
     <(cd /fbkup ; find . -type f -print | sort) | \
     awk '/^</ {gsub(/^</,""); print}'
  • 1
    very good ! it probably wont get better than that until the author of comm adds a -n switch to negate the -1 and -2 option. – Andreas Jan 18 '13 at 2:41

Don't use diff, use join instead. Since your input files are already sorted, the following should produce exactly the output you requested:

join -v 2 /tmp/invent.txt /tmp/backup.txt > /tmp/in-backup-but-not-invent.txt

(If the file paths in either /tmp/backup.txt or /tmp/invent.txt contain whitespace, then join may not work correctly with the options given above. In that case, you will have to look at using the -t option, to specify a non-whitespace char as the field separator for join. You would want to choose as field separator a char that does not actually appear in any of your file paths. Something like | or \ would probably suffice.)

for i in `cat /tmp/invent.txt`; do grep ^$i$ /tmp/backup.txt >/dev/null || echo $i ; done

This will echo all names in /tmp/invent.txt which is not in /tmp/backup.txt


I found another way using diff :- (diff -r dir1 dir2)

-r, --recursive means Recursively compare any subdirectories found.

$ mkdir -p dir1/dir dir2/dir/dir

$ diff -r dir1 dir2
Only in dir2/dir: dir

$ touch dir1/file{a..d}

$ touch dir2/file{a..d}

$ touch dir2/dir/file{a..d}

$ echo hi >  dir2/filea

$ diff -q -r dir1 dir2
Only in dir2/dir: dir
Only in dir2/dir: filea
Only in dir2/dir: fileb
Only in dir2/dir: filec
Only in dir2/dir: filed
Files dir1/filea and dir2/filea differ
  • 4
    clumsy... clumsy... 100,000 x 100,000 = 10 billion compares 1 – Andreas Jan 18 '13 at 1:43
  • @Andreas see my edit. I found a more efficient way to compare directories. :) – Suku Jan 18 '13 at 4:35
  • Thanks for trying to find a solution. See above, read my problem description, look how the 2 text files were obtained, aren't you solving another, very different problem? – Andreas Jan 19 '13 at 20:26
  • Hmmm... Using diff -r you can find out the difference between two directories. Thats it. – Suku Jan 20 '13 at 1:47

Diff can prolly do this, but im too lazy to check.

Try comm. comm -2 -3 or comm -1 -2 which'll give lines only in file A, or lines only in file B.

  • 4
    This seems to be what he wants, but according to my manpage it looks like -1 and -2 turn OFF those outputs, not on. comm -23 turns off "lines unique to file 2" and "lines in both files" to print only lines in file 1 – DerfK Jan 18 '13 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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