1

I want a simple bash command to compare two hash values that outputs whether they are the same. Here's what I've tried:

md5sum file1 | awk '{print $1}' # outputs hash value without filename

md5sum file1 > md5sum file2 # no output even though files/hashes differ

I've tried variations on the following with no success so far:

[ md5sum states.txt | awk '{print $1}' == md5sum states_copy.txt | awk '{print $1}' ]

[ (md5sum states.txt | awk '{print $1}') == (md5sum states_copy.txt | awk '{print $1}') ]

I'm open to a script or multi-line bash solution, or using shasum, but I'm new to Linux and bash so trying to keep it as simple as possible.

I'm running Ubuntu 18.04.

Karl Baker
  • 903
  • 12
  • 27
  • 3
    Possible duplicate of [How do I compare two string variables in an 'if' statement in Bash?](https://stackoverflow.com/questions/4277665/how-do-i-compare-two-string-variables-in-an-if-statement-in-bash) – Adam Ostrožlík Sep 12 '18 at 08:50
  • 1
    Just wondering, but why are you not using `if diff -q $file1 $file2 &>/dev/null; then do_your_stuff; fi` or even better `if cmp --silent $file1 $file2; then do_your_stuff; fi` – kvantour Sep 12 '18 at 09:19
  • @kvantour, I am new to bash and there's a lot I don't quite understand in your suggestions. From the syntax am I correct to see your suggestions as scripts, and `$file1` etc. as variables passed in from the command line? I tried running your first suggestion on the command line with the filenames hardcoded, then printing the output with `echo $?`, but didn't find the results I expected. Can you expand a bit on what I would want to do on the `do_your_stuff` line? Could I put an `echo ...` there to print out the result of the diff comparison, and if so, how would I capture that result? – Karl Baker Sep 14 '18 at 01:19
  • Your original question is to compare two md5sum which are computed on the fly. So you do not have them stored in any variable or anything. This implies that you are actually trying to figure out if two files are identical or not. The command `cmp` and `diff` do exactly that. So you can just check the return codes of those commands. `cmp --silent file1 file2` or `diff -q file1 file2 &> /dev/null` – kvantour Sep 14 '18 at 10:27

2 Answers2

5
[ "$(<states.txt md5sum)" = "$(<states_copy.txt md5sum)" ]
  1. Use $(...) to get command output
  2. Remember to enclose $(...) inside "
  3. Bash test supports single = for string comparision, not double ==
  4. Redirect the files into md5sum using stdin and using < redirection.
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

there are many ways to do it, since you used awk, you may try:

md5sum f1 f2|awk '{a[$1]}END{print NR==length(a)}'

If the two hashes are same, output 0 otherwise 1. you can add more files to md5sum:

md5sum f1 f2 f3...fn|awk '{a[$1]}END{print NR==length(a)}'
Kent
  • 189,393
  • 32
  • 233
  • 301
  • Maybe better to use `exit` instead of `print` this way it can be used in an `if`-statement. – kvantour Sep 12 '18 at 09:14
  • 1
    You should mention that not all awks will support `length(array)` (it's not part of POSIX). – Ed Morton Sep 12 '18 at 13:10
  • 1
    @Kent, when I run the following: `$ md5sum states6.txt states_copy.txt | awk '{a[$1]}END{print NR==length(a)}'` I get the following error as output: `awk: line 1: illegal reference to array a`. I'm on a Linux only system, Ubuntu 18.04, if that makes a difference. – Karl Baker Sep 12 '18 at 22:09
  • @KarlBaker as Ed commented, length() is gnu extension. pls check which version your awk has. Don't use ubuntu, I cannot tell. If you are using gawk, the line should work. – Kent Sep 13 '18 at 08:09
  • Thanks, @Kent! I installed gawk and ran it with gawk and it worked. – Karl Baker Sep 14 '18 at 00:18