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?
Asked
Active
Viewed 9,301 times
12
-
6try this: `diff <(echo "$string1") <(echo "$string2")` – riteshtch May 30 '16 at 10:35
-
Hi! That gives me `syntax error near unexpected token '(': diff <(echo "$S1") <(echo "$S2")'`. Note: this is OS X, but I'm not sure that's the problem. – entonio May 30 '16 at 10:41
-
I should point out that my bash (3.2.57) doesn't seem to support the `<(...)` syntax, regardless of what's inside. I know I tagged this with 'bash', but if possible I'd like a generic answer (though any answer at all would be helpful!), – entonio May 30 '16 at 10:51
-
2`I have a script with two multiline strings.` Would you mind posting the script? – sjsam May 30 '16 at 10:59
-
2Are you using `#!/bin/bash` or `#!/bin/sh`? – Will May 30 '16 at 11:42
-
You can check question: http://stackoverflow.com/questions/31540902/how-to-check-if-one-file-is-part-of-other – abrzozowski May 30 '16 at 12:57
-
1`bash` 3.2 absolutely supports process substitution, but not if it is run as `sh`. – chepner May 30 '16 at 13:22
-
1@Will and @chepner, you were right. Changing to `#!/bin/bash` made @ritesht93's `diff` work. What should I do regarding the question now? – entonio May 31 '16 at 13:54
-
I would use `diff <(echo "$string1") <(echo "$string2")` or `cmp <(echo "$string1") <(echo "$string2")` – Will May 31 '16 at 17:05
3 Answers
7
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
foo='this
is
a
string'
bar='this
is not
the same
string'
[ "$foo" = "$foo" ] && echo SUCCESS || echo FAILURE
[ "$foo" != "$bar" ] && echo SUCCESS || echo FAILURE
$ /tmp/multiline.sh
SUCCESS
SUCCESS
In bash
you can (and generally should) use [[ ... ]]
instead of [ ... ]
, but they both still support multiline strings.

dimo414
- 47,227
- 18
- 148
- 244
-
But hey! Both the Equal and Not-equal comparison return the same `SUCCESS` here. I guess something is wrong. – saulius2 Sep 17 '22 at 16:01
-
1@saulius2 They're comparing different values - `$var = $var` vs. `$var != $var2`. The "SUCCESS" indicates the comparison (equals or not-equals) behaved correctly. – dimo414 Sep 18 '22 at 17:28
-
6
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,293
- 11
- 10
-
31. 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
-
-
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
- 40,270
- 28
- 126
- 178