bash - Finde den Unterschied zwischen zwei Variablen

1851
Lejour

Ich habe zwei Variablen: var1="1, 2, 3, 4"und var2="3, 4, 5, 6".
Ich möchte eine neue, var3, mit den Unterschieden zwischen $var1und $var2.
Das erwartete Ergebnis sollte sein var3=1, 2, 5, 6.

Ich habe es versucht, diffaber die Ausgabe ist nicht das, was ich wollte:

diff <(echo "$var1") <(echo "$var2") 
1c1 < 1, 2, 3, 4 --- > 3, 4, 5, 6 

Welche andere Lösung erlaubt es mir var3, eine Datei zu erstellen?

1
Einige zusätzliche Hinweise ... Genießen Sie SuperUser und `bash` ... Hastur vor 6 Jahren 0

3 Antworten auf die Frage

2
Hastur

Es gibt viele Wege...

  • Sie können verwendet werden sort, tr uniqueund pasteund $()sie auszuführen, und „die Ausgabe in einer Variablen - Transformation“

    #!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo " $, $" | tr ',' '\n' | sort | uniq -u | paste -sd,) echo $var3 
    1, 2, 5, 6 

    Für jeden der vorherigen Befehle können Sie mehr lesen mit z man sort

  • Sie können die Variable in Bash-Arrays transformieren und daran arbeiten (nehmen Sie die folgenden Anweisungen als Hinweis, da es unzählige Möglichkeiten gibt, sie zu realisieren ...)

    #!/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 "$"; do Found=0 for j in "$"; 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 "$"; do Found=0 for i in "$"; do [[ "$i" -eq "$j" ]] && Found=1 done  [[ $Found == 0 ]] && { var3="$var3$SEP$j" ; SEP=", "; } done  echo $var3 
  • verwenden awk(oder um genau zu sein gawk)

    #!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo "$var1, $var2" | \ awk -F ',' ' }  END{ SEP="";  for (i in A)  } }' ) echo $var3 

Hinweis: Der zweite und der dritte Ausgang sind nicht bestellt ...


Aktualisierte Hinweise : ... und es gibt ein Leerzeichen vor $var1und $var2da in Ihrem komischen ( :-)) Format Leerzeichen hinter dem Komma ( ,) stehen, müssen Sie also besonders auf alle Befehle achten, bei denen nur ein Zeichen als Trennzeichen verwendet wird Problem, wenn es eine , 1in der zweiten Saite gab ... was Sie nicht finden man <command>können, können Sie versuchen mit man bashoder mit help command...

Ad-Übelkeit :

  • diffStil, im Sinne Ihres Versuchs ... vielleicht können Sie nach einem gemütlicheren Ausgabeformat suchen ( 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, 
Vielen Dank! Funktioniert auch unter Berücksichtigung von Sonderzeichen. Lejour vor 6 Jahren 0
@Lejour Gern geschehen ... und herzlich willkommen bei SuperUser. Sogar die anderen Antworten scheinen zu funktionieren. Probieren Sie die Antworten aus, die Sie für richtig und nützlich halten. Wählen Sie die, die Sie als Antwort für Ihre Frage bevorzugen, und genießen Sie die Site. Hastur vor 6 Jahren 0
0
glenn jackman

Ich habe keine Zeit für eine vollständige Erklärung, aber:

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 
0
Jaroslav Kucera

Andere 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/,//' 

Und Renn

$ ./test.sh  1,2,5,6