Reputation: 1197
I have a variable $data
and variable $file
in a bash script:
data=$(echo "$(printf '%s\n' "${array[@]/%/$'\n\n'}")")
file=$(<scriptfile_results)
Those variables will contain text. How to compare those two? One option is to use diff(1) utility like this:
diff -u <(echo "$data") <(echo "$file")
Is this an correct and elegant way to compare content of two variables? In addition how is the <( )
technique called? As I understand, for each <( )
a temporary file(named pipe) is created..
Upvotes: 72
Views: 79383
Reputation: 1981
Using comm
:
comm -23 <(echo $variableA | tr ' ' '\n' | sort) <(echo $variableB | tr ' ' '\n' | sort)
Upvotes: 3
Reputation: 31
~ cat test.sh
#!/usr/bin/env bash
array1=(cat dog mule pig)
array2=(cat dog ant)
diff -ia --suppress-common-lines <( printf "%s\n" "${array1[@]}" ) <( printf "%s\n" "${array2[@]}" )
Upvotes: 3
Reputation: 197
This works best for me:
var1="cat dog mule pig"
var2="cat dog ant"
diff <( echo "$var1" ) <( echo "$var2" )
First I set var1 and var2. Then I diff with <( ) elements to say that the input is a variable.
Upvotes: 7
Reputation: 34873
Yes, diff <(echo "$foo") <(echo "$bar")
is fine.
By searching the bash manpage for the characters <(
, you can find that this is called “process substitution.”
You don't need to worry about the efficiency of creating a temporary file, because the temporary file is really just a pipe, not a file on disk. Try this:
$ echo <(echo foo)
/dev/fd/63
This shows that the temporary file is really just the pipe “file descriptor 63.” Although it appears on the virtual /dev
filesystem, the disk is never touched.
The actual efficiency issue that you might need to worry about here is the ‘process’ part of “process substitution.” Bash forks another process to perform the echo foo
. On some platforms, like Cygwin, this can be very slow if performed frequently. However, on most modern platforms, fork
ing is pretty fast. I just tried doing 1000 process substitutions at once by running the script:
echo <(echo foo) <(echo foo) ... 997 repetitions ... <(echo foo)
It took 0.225s on my older Mac laptop, and 2.3 seconds in a Ubuntu virtual machine running on the same laptop. Dividing by the 1000 invocations, this shows that process substitutions takes less than 3 milliseconds—something totally dwarfed by the runtime of diff
, and probably not anything you need to worry about!
Upvotes: 127
Reputation: 212634
test "$data" = "$file" && echo the variables are the same
If you wish to be verbose, you can also do:
if test "$data" = "$file"; then
: variables are the same
else
: variables are different
fi
Upvotes: 7