web-dev-qa-db-fra.com

Différence de chaîne dans Bash

J'essaie de trouver un moyen de déterminer la différence entre deux chaînes dans mon script. Je pourrais facilement le faire avec diff ou comm, mais je ne traite pas de fichiers et je préférerais ne pas les exporter vers des fichiers, faire la comparaison et les relire.

Je vois que comm, diff, cmp permettent tous de passer soit deux fichiers OR un fichier et une entrée standard - je suppose que c'est bien si je ne veux pas sortir deux fichiers ... mais c'est suce toujours un peu.

Je fouille en pensant que je peux utiliser grep ou des expressions régulières - mais je suppose que non.

95
newbrand

En utilisant diff ou com ou ce que vous voulez:

diff  <(echo "$string1" ) <(echo "$string2")

FAQ de Greg's Bash: Substitution de processus

ou avec un tuyau nommé

mkfifo ./p
diff - p <<< "$string1" & echo "$string2" > p

FAQ de Greg's Bash: Travailler avec des canaux nommés

Le tube nommé est également appelé FIFO.

Le - seul est pour l'entrée standard.

<<< est une "chaîne ici".

& est comme ; mais le met en arrière-plan

164
Ian Kelling

Me rappelle cette question: Comment pouvez-vous différencier deux pipelines dans Bash?

Si vous êtes dans une session bash, vous pouvez faire:

diff <cmd1 <cmd2
diff <(foo | bar) <(baz | quux)

avec < création de canaux nommés anonymes - gérés par bash - afin qu'ils soient créés et détruits automatiquement, contrairement aux fichiers temporaires.

Donc, si vous parvenez à isoler vos deux chaînes différentes dans le cadre d'une commande (grep, awk, sed, ...), vous pouvez faire - par exemple - quelque chose comme:

diff < grep string1 myFile < grep string2 myFile

(si vous supposez que vous avez dans votre fichier des lignes comme string1=very_complicated_value et un string2=another_long_and_complicated_value': sans connaître le format interne de votre fichier, je ne peux pas recommander une commande précise)

13
VonC

Je préfère cmp et la fonction de substitution de processus de bash:

$ cmp -bl <(echo -n abcda) <(echo -n aqcde)
  2 142 b    161 q
  5 141 a    145 e

Dire en position 2, un b se produit pour le premier, mais un q pour le second. En position 5, une autre différence se produit. Remplacez simplement ces chaînes par des variables, et vous avez terminé.

12

Disons que vous avez trois cordes

a="this is a line"
b="this is"
c="a line"

Pour supprimer le préfixe b d'un

echo ${a#"$b"}  # a line

Pour supprimer le suffixe c d'un

echo ${a%"$c"}  # this is
11
Pithikos

Un autre exemple:

before="184613 102050 83756 63054"
after="184613 102050 84192 83756 63054"

comm -23 <(tr ' ' $'\n' <<< $after | sort) <(tr ' ' $'\n' <<< $before | sort)

Les sorties

84192

Réponse originale ici

0
Sida Zhou