J'ai deux tableaux comme celui-ci:
A=(vol-175a3b54 vol-382c477b vol-8c027acf vol-93d6fed0 vol-71600106 vol-79f7970e vol-e3d6a894 vol-d9d6a8ae vol-8dbbc2fa vol-98c2bbef vol-ae7ed9e3 vol-5540e618 vol-9e3bbed3 vol-993bbed4 vol-a83bbee5 vol-ff52deb2)
B=(vol-175a3b54 vol-e38d0c94 vol-2a19386a vol-b846c5cf vol-98c2bbef vol-7320102b vol-8f6226cc vol-27991850 vol-71600106 vol-615e1222)
Les tableaux ne sont pas triés et peuvent même contenir des éléments dupliqués.
Je voudrais faire l'intersection de ces deux tableaux et stocker les éléments dans un autre tableau. Comment ferais-je ça?
De plus, comment puis-je obtenir la liste des éléments qui apparaissent en B et qui ne sont pas disponibles en A?
foo
deux fois), avez-vous besoin qu'ils soient dupliqués dans le résultat?Réponses:
comm(1)
est un outil qui compare deux listes et peut vous donner l'intersection ou la différence entre deux listes. Les listes doivent être triées, mais c'est facile à réaliser.Pour obtenir vos tableaux dans une liste triée adaptée à
comm
:Cela transformera le tableau A en une liste triée. Faites de même pour B.
Pour utiliser
comm
pour renvoyer l'intersection:-1 -2
dit de supprimer les entrées uniques au fichier1 (A) et uniques au fichier2 (B) - l'intersection des deux.Pour qu'il renvoie ce qui est dans le fichier2 (B) mais pas dans le fichier1 (A):
-1 -3
dit de supprimer les entrées uniques à file1 et communes aux deux - ne laissant que celles uniques à file2.Pour alimenter deux pipelines
comm
, utilisez la fonction "Substitution de processus" debash
:Pour capturer cela dans un tableau:
Mettre tous ensemble:
la source
\n
.\n
essayez ceci:arr1=( one two three "four five\nsix\nseven" ); arr2=( ${arr1[@]:1} "four five\\nsix" ); n1=${#arr1[@]}; n2=${#arr2[@]}; arr=( ${arr1[@]/ /'-_-'} ${arr2[@]/ /'-_-'} ); arr=( $( echo "${arr[@]}"|tr '\t' '-t-'|tr '\n' '-n-'|tr '\r' '-r-' ) ); arr1=( ${arr[@]:0:${n1}} ); arr2=( ${arr[@]:${n1}:${n2}} ); unset arr; printf "%0.s-" {1..10}; printf '\n'; printf '{'; printf " \"%s\" " "${arr1[@]}"; printf '}\n'; printf "%0.s-" {1..10}; printf '\n'; printf '{'; printf " \"%s\" " "${arr2[@]}"; printf '}\n'; printf "%0.s-" {1..10}; printf '\n\n'; unset arr1; unset arr2
LC_ALL=C
. Au lieu de cela, réglezLC_COLLATE=C
le même gain de performances sans autres effets secondaires. Afin d'obtenir des résultats corrects, vous devrez également définir le même classement quecomm
celui utilisé poursort
, par exemple:unset LC_ALL; LC_COLLATE=C ; comm -12 <(printf '%s\n' "${A[@]}" | sort) <(printf '%s\n' "${B[@]}" | sort)
Vous pouvez obtenir tous les éléments qui se trouvent à la fois dans A et B en parcourant les deux tableaux et en comparant:
Vous pouvez obtenir tous les éléments en B mais pas en A de la même manière:
la source
A
etB
, est-ceintersections
toujours la même chose pour réorganiser?Il existe une approche assez élégante et efficace pour ce faire, en utilisant
uniq
- mais, nous devrons éliminer les doublons de chaque tableau, ne laissant que des éléments uniques. Si vous souhaitez enregistrer les doublons, il n'y a qu'une seule façon "de parcourir les deux tableaux et de comparer".Considérez que nous avons deux tableaux:
Tout d'abord, transformons ces tableaux en ensembles. Nous le ferons parce qu'il ya intersection opération mathématique qui est connu comme intersection des ensembles, et ensemble est une collection de différents objets, distincts ou uniques . Pour être honnête, je ne sais pas ce qu'est "l'intersection" si nous parlons de listes ou de séquences. Bien que nous puissions choisir une sous-séquence de la séquence, mais cette opération (sélection) a une signification légèrement différente.
Alors, transformons-nous!
Intersection:
Si vous souhaitez stocker les éléments dans un autre tableau:
uniq -d
signifie ne montrer que les doublons (je pense,uniq
c'est assez rapide à cause de sa réalisation: je suppose que c'est fait enXOR
fonctionnement).Obtenez la liste des éléments qui apparaissent
B
et qui ne sont pas disponibles dansA
, c.- à -d.B\A
Ou, avec sauvegarde dans une variable:
Ainsi, au début, nous avons obtenu l'intersection de
A
etB
(qui est simplement l'ensemble des doublons entre eux), disons que c'est le casA/\B
, puis nous avons utilisé l'opération d'inversion de l'intersection deB
etA/\B
(qui n'est tout simplement que des éléments uniques), nous obtenons doncB\A = ! (B /\ (A/\B))
.PS a
uniq
été écrit par Richard M. Stallman et David MacKenzie.la source
Ignorant l'efficacité, voici une approche:
la source
Ma pure façon bash
Comme ces variables contiennent uniquement
vol-XXX
oùXXX
est un nombre hexadécimal, il existe un moyen rapide d'utiliser les tableaux bashCela doit produire:
À cet état, votre environnement bash contient:
Vous pourriez donc:
Cela rendra:
Mais c'est trié numériquement! Si vous souhaitez une commande originale, vous pouvez:
Donc, vous affichez les vols dans le même ordre que celui soumis:
ou
pour afficher uniquement en A :
ou même:
sera réimprimer :
la source
Duplicate
lignes sont inutiles, elles pourraient simplement être supprimées.