0

Cannot use diff and cannot use cmp.

We are able to use comm with success, but I am not getting the correct results when used with a conditional in script.

#!/bin/bash
# http://stackoverflow.com/a/14500821/175063

comm -23 <(sort /home/folder/old.txt) <(sort /home/folder/new.txt)
if [ $? -eq 0 ];then
   echo "There are no changes in the files"
else
   echo "New files were found. Return code was $?"
fi

It always returns:

There are no changes in the files

as the comm command, runs successfully but the contents of the files are different.

I am very limited as to what can be added to this server as it is a corporate LINUX box.

Leptonator
  • 3,033
  • 1
  • 33
  • 47
  • 1
    `comm` always return 0 even on failure such as file not found. You need to check stdout to see if `comm` has output. – alvits Jul 12 '16 at 00:33
  • What do the files look like? You know that `$?` is the exit status of the last process and not the number of lines? – dawg Jul 12 '16 at 00:34
  • 1
    Ditto on `$?`. Also, `comm -23` returns line in old.txt that are not in new.txt. Lines in new.txt that are not in old.txt are ignored. Is that what you want? – John1024 Jul 12 '16 at 00:35
  • Yes comm -23 will show the difference with the name of the files. I am pretty sure the exit code is not what is needed in this example. I want to look for if there is a difference in the content of the files in the folder to alert me, otherwise wait until the next time the script runs. – Leptonator Jul 12 '16 at 00:40
  • Can you use `awk`? – dawg Jul 12 '16 at 00:53
  • _"Yes comm -23 will show the difference with the name of the files."_ No, it doesn't, not like `diff` or `cmp` anyway. It shows output _only if_ there are lines in old that are not in new. – John1024 Jul 12 '16 at 00:57

2 Answers2

3

You should be able to use:

! comm -3 <(sort /home/folder/old.txt) <(sort /home/folder/new.txt) | grep -q '.*'

The comm command will succeed (exit with status 0) whether it finds any differences or not, but grep only succeeds if it finds a match. -q prevents grep from printing the match(es), and the pattern '.*' matches anything. Thus, grep -q '.?' succeeds if its input is nonempty. But you wanted success if there was a match, so I added the ! at the beginning to invert the status.

I also made one other change: comm -23 will print lines that're in the first file (old.txt) and not in the second one (new.txt), but it will not print lines that're in the second but not the first. comm -3 will print all lines that're unique to one of the files, so it'll find lines that've been removed or added between the two files.

BTW, testing whether $? is zero is unnecessary; just use the command directly as the if condition:

if ! comm -3 <(sort /home/folder/old.txt) <(sort /home/folder/new.txt) | grep -q '.*'; then
   echo "There are no changes in the files"
else
   echo "New files were found. Return code was $?"
fi
Gordon Davisson
  • 95,980
  • 14
  • 99
  • 125
0

Pipe the output of comm to wc -l to see if there were any new files found.

new_file_count=$(comm -13 <(sort /home/folder/old.txt) <(sort /home/folder/new.txt) | wc -l)
if [ $new_file_count -eq 0];then
   echo "There are no changes in the files"
else
   echo "New files were found. Count is $new_file_count"
fi

I changed the comm command to use -13 so it will print the new files, since that's what your message suggests you want.

Barmar
  • 596,455
  • 48
  • 393
  • 495
  • Not count. The files are updated from a vendor. Like file 101.dat would be updated to 102.dat and file 101.dat would be deleted. We want to know if file 102.dat in this example we would then be notified. – Leptonator Jul 12 '16 at 01:22
  • This counts the number of lines that are in `new.txt` that aren't in `old.txt`. So the count will be `1` because `102.dat` is in the new file, but not in the old one. – Barmar Jul 12 '16 at 01:25
  • Deleted lines are not counted, they would be counted by `comm -23`. – Barmar Jul 12 '16 at 01:25