compare content of two variables in bash

BashDiff

Bash Problem Overview


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..

Bash Solutions


Solution 1 - Bash

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, forking 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!

Solution 2 - Bash

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

Solution 3 - Bash

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.

Solution 4 - Bash

~ 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[@]}" )

Solution 5 - Bash

Using comm:

comm -23 <(echo $variableA | tr ' ' '\n' | sort) <(echo $variableB | tr ' ' '\n' | sort)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartinView Question on Stackoverflow
Solution 1 - BashandrewdotnView Answer on Stackoverflow
Solution 2 - BashWilliam PursellView Answer on Stackoverflow
Solution 3 - BashdeterminacyView Answer on Stackoverflow
Solution 4 - BashdeadElkView Answer on Stackoverflow
Solution 5 - BashimrissView Answer on Stackoverflow