bash - Find difference between two variables
Solution 1
There are many ways...
You can use
sort
,tr
unique
andpaste
and$()
to execute them and "transform the output in a variable"#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo " ${var1}, ${var2}" | tr ',' '\n' | sort | uniq -u | paste -sd,) echo $var3
1, 2, 5, 6
For each of the previous commands you can read more with e.g.
man sort
You can transform the variable in bash arrays and work on them (take the follow just as a hint because there is an uncountable number of ways to realize it...)
#!/bin/bash#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" # here you transform the variable in array IFS=',' read -ra ADDR <<< "$var1" IFS=',' read -ra ADDR2 <<< "$var2" # then for each element in the 1st array you search if in the 2nd too SEP=""; var3="" for i in "${ADDR[@]}"; do Found=0 for j in "${ADDR2[@]}"; do [[ "$i" -eq "$j" ]] && Found=1 done [[ $Found == 0 ]] && { var3="$var3$SEP$i" ; SEP=", "; } done # then for each element in the 2nd array you search if in the 1st too for j in "${ADDR2[@]}"; do Found=0 for i in "${ADDR[@]}"; do [[ "$i" -eq "$j" ]] && Found=1 done [[ $Found == 0 ]] && { var3="$var3$SEP$j" ; SEP=", "; } done echo $var3
using
awk
(or to be precisegawk
)#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo "$var1, $var2" | \ awk -F ',' '{for (i=1;i<=NF;i++) {A[$i]++;} } END{ SEP=""; for (i in A) {if (A[i]==1){ printf ("%s%s", SEP,i); SEP=", "} } }' ) echo $var3
Note: the second and the third one outputs are not ordered...
Updated Notes: ...and there is a space before $var1
and $var2
because in your weird (:-)
) format there are spaces after the comma (,
) so you need special care for all the commands that take only one character as separator... this fix the problem if there was an , 1
in the second string...what are you not able to find with man <command>
you can try to find with man bash
or with help command
...
Ad nauseam:
diff
style, in the spirit of your attempt... maybe you can search for an output format more cozy (man diff
)diff --ignore-all-space \ <(echo "$var1" | tr ',' '\n' ) <(echo "$var2" | tr ',' '\n')\ | grep -v "^---" | grep -v "^[0-9c0-9]" | tr -d '<||>|| |' \ | paste -sd,
Solution 2
I don't have time for a full explanation, but:
var1="1, 2, 3, 4"; var2="3, 4, 5, 6"
comm -3 <(grep -oP '\d+' <<<"$var1" | sort) <(grep -oP '\d+' <<<"$var2" | sort) |
tr -d '\t' |
paste -sd,
1,2,5,6
Solution 3
Another option:
#!/usr/bin/bash
var1="1, 2, 3, 4"
var2="3, 4, 5, 6"
out=""
for num in `echo $var1,$var2 | tr -d " "| tr "," "\n " | sort | uniq | tr "\n" " "`
do
if (`grep -v $num <<< "$var1" >/dev/null 2>&1` || `grep -v $num <<< "$var2" >/dev/null 2>&1`)
then
out="$out,$num"
fi
done
echo $out | sed -e 's/,//'
And run
$ ./test.sh
1,2,5,6
Related videos on Youtube

Lejour
Updated on September 18, 2022Comments
-
Lejour 4 months
I have two variables:
var1="1, 2, 3, 4"
andvar2="3, 4, 5, 6"
.
I'd like to get a new one, var3, containing the differences between$var1
and$var2
.
The expected result should bevar3=1, 2, 5, 6
.I tried
diff
but the output is not what I wanted:diff <(echo "$var1") <(echo "$var2")
1c1 < 1, 2, 3, 4 --- > 3, 4, 5, 6
Which other solution allows me to have
var3
without creating any file?-
Hastur about 5 yearsSome additional hints... Enjoy SuperUser and
bash
...
-
-
Lejour about 5 yearsThanks! Works perfectly considering special characters as well.
-
Hastur about 5 years@Lejour You're welcome... and welcome on SuperUser. Even the other answers seem to work. Try and upvote the answers you find correct and useful. Choose the one you prefer as the answer for your question and enjoy the site.