8

I have a script with two multiline strings. I'd like to know if they are equal. I haven't found a way to do this, because while comparing is easy, passing the value of the variables to the comparison thingamajig isn't. I haven't had success piping it to diff, but it could be my ineptitude (many of the things I've tried resulted in 'File name too long' errors). A workaround would be to replace newlines by some rare character, but it meets much the same problem. Any ideas?

entonio
  • 2,063
  • 1
  • 17
  • 26

3 Answers3

5

This might be helpful:

var=$(echo -e "this\nis \na\nstring" | md5sum)
var2=$(echo -e "this\nis not\na\nstring" | md5sum)
if [[ $var == $var2 ]] ; then echo true; else echo false; fi
Michael Vehrs
  • 3,202
  • 10
  • 10
  • 3
    1. You better use ${} in stead of $(). 2. You don't need to use md5sum... you can just compare the strings "as is" – I-V May 30 '16 at 13:18
  • 1
    @I-V `${...}` cannot be used in place of `$(...)`. You are right about `md5sum`, though. – chepner May 30 '16 at 13:23
  • Why not {}? (I really want to understand :) ) – I-V May 30 '16 at 13:30
  • 1
    @I-V `${var}` is variable expansion, `$(date)` is command substitution. – Michael Vehrs May 30 '16 at 14:54
  • Yes, this can probably be done directly. However, the OP mentions a problem passing the multi-line strings to a comparison. What is that problem exactly? – Michael Vehrs May 30 '16 at 15:09
  • I'm accepting this one as it seems to work with `#!/bin/sh`. Without that restriction, plain diff works, as discussed in the question comments. – entonio May 31 '16 at 15:52
4

Working with bats and bats-assert I sued the solution from @dimo414 (upvote his answer)

@test "craft a word object" {
  touch "$JSON_FILE"
  entry=$(cat <<-MOT
  {
    "key": "bonjour",
    "label": "bonjour",
    "video": "video/bonjour.webm"
  },
MOT
)

  run add_word "bonjour"

  content=$(cat $JSON_FILE)
  assert_equal "$entry" "$content"
}
Édouard Lopez
  • 36,430
  • 24
  • 114
  • 170
3

Even if you're using sh you absolutely can compare multiline strings. In particular there's no need to hash the strings with md5sum or another similar mechanism.

Demo:

$ cat /tmp/multiline.sh
#!/bin/sh

var='this
is
a
string'

var2='this
is not
a
string'

[ "$var" = "$var" ]   && echo SUCCESS || echo FAILURE
[ "$var" != "$var2" ] && echo SUCCESS || echo FAILURE

$ /tmp/multiline.sh
SUCCESS
SUCCESS

In bash you can (and generally should) use [[ ... ]] instead of [ ... ], but the latter still supports multiline strings.

Arminius
  • 1,871
  • 17
  • 19
dimo414
  • 44,897
  • 17
  • 143
  • 228