bash - Find difference between two variables
Solution 1
There are many ways...
You can use
sort,truniqueandpasteand$()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 $var31, 2, 5, 6For each of the previous commands you can read more with e.g.
man sortYou 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 $var3using
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:
diffstyle, 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 monthsI 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$var1and$var2.
The expected result should bevar3=1, 2, 5, 6.I tried
diffbut the output is not what I wanted:diff <(echo "$var1") <(echo "$var2")1c1 < 1, 2, 3, 4 --- > 3, 4, 5, 6Which other solution allows me to have
var3without creating any file?-
Hastur about 5 yearsSome additional hints... Enjoy SuperUser andbash...
-
-
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.