3

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 ...

4 Answers 4

3

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
  • 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, 2013 at 2:41
3

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.)

0
3
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

Edit

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
  • 4
    clumsy... clumsy... 100,000 x 100,000 = 10 billion compares 1
    – Andreas
    Jan 18, 2013 at 1:43
  • @Andreas see my edit. I found a more efficient way to compare directories. :)
    – Suku
    Jan 18, 2013 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, 2013 at 20:26
  • Hmmm... Using diff -r you can find out the difference between two directories. Thats it.
    – Suku
    Jan 20, 2013 at 1:47
2

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.

1
  • 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, 2013 at 1:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .