Tengo dos matrices como esta:
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)
Las matrices no están ordenadas y posiblemente podrían contener elementos duplicados.
Me gustaría hacer la intersección de estas dos matrices y almacenar los elementos en otra matriz. ¿Como podría hacerlo?
Además, ¿cómo obtendría la lista de elementos que aparecen en B y no están disponibles en A?

foodos veces), ¿los necesita duplicados en el resultado?Respuestas:
comm(1)es una herramienta que compara dos listas y puede darle la intersección o diferencia entre dos listas. Las listas deben ordenarse, pero eso es fácil de lograr.Para obtener sus matrices en una lista ordenada adecuada para
comm:Eso convertirá la matriz A en una lista ordenada. Haz lo mismo para B.
Para usar
commpara devolver la intersección:-1 -2dice que elimine las entradas exclusivas del archivo1 (A) y exclusivas del archivo2 (B): la intersección de las dos.Para que devuelva lo que está en el archivo 2 (B) pero no en el archivo 1 (A):
-1 -3dice que elimine las entradas exclusivas de file1 y comunes a ambas, dejando solo aquellas exclusivas de file2.Para alimentar dos tuberías
comm, utilice la función "Sustitución de proceso" debash:Para capturar esto en una matriz:
Poniendolo todo junto:
fuente
\n.\nintente esto: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 arr2LC_ALL=C. En cambio, establezcaLC_COLLATE=Cla misma ganancia de rendimiento sin otros efectos secundarios. Para obtener resultados correctos , también deberá establecer la misma clasificación para lacommque se utilizósort, por ejemplo:unset LC_ALL; LC_COLLATE=C ; comm -12 <(printf '%s\n' "${A[@]}" | sort) <(printf '%s\n' "${B[@]}" | sort)Puede obtener todos los elementos que están en A y B recorriendo ambas matrices y comparando:
Puede obtener todos los elementos en B pero no en A de manera similar:
fuente
AyB, ¿esintersectionssiempre igual reordenar?Para hacerlo, hay un enfoque bastante elegante y eficiente,
uniqpero tendremos que eliminar duplicados de cada matriz, dejando solo elementos únicos. Si desea guardar duplicados, solo hay una forma "recorriendo ambas matrices y comparando".Considere que tenemos dos matrices:
En primer lugar, transformemos estas matrices en conjuntos. Lo haremos porque no es matemática intersección operación que se conoce como la intersección de conjuntos, y el conjunto es una colección de distintos objetos, diferentes o únicas . Para ser honesto, no sé qué es "intersección" si hablamos de listas o secuencias. Aunque podemos seleccionar una subsecuencia de la secuencia, pero esta operación (selección) tiene un significado ligeramente diferente.
Entonces, ¡vamos a transformar!
Intersección:
Si desea almacenar los elementos en otra matriz:
uniq -dsignifica mostrar solo duplicados (creo queuniqes bastante rápido debido a su realización: supongo que se hace con laXORoperación).Obtenga la lista de elementos que aparecen
By no están disponiblesA, es decirB\AO, al guardar en una variable:
Por lo tanto, al principio tenemos la intersección de
AyB(que es simplemente el conjunto de duplicados entre ellos), digamos que esA/\B, y luego utilizamos la operación de la intersección invertida deByA/\B(que simplemente son elementos únicos), por lo que obtenemosB\A = ! (B /\ (A/\B)).PS
uniqfue escrito por Richard M. Stallman y David MacKenzie.fuente
Ignorando la eficiencia, aquí hay un enfoque:
fuente
Mi puro estilo bash
Como estas variables contienen solo
vol-XXXdondeXXXhay un número hexadecimal, hay una forma rápida de usar matrices bashEsto debe generar:
En este estado, su entorno bash contiene:
Entonces podrías:
Esto rendirá:
¡Pero esto está ordenado numéricamente! Si desea un pedido original, podría:
Por lo tanto, muestra los vols en el mismo orden en que los envió:
o
para mostrar solo en A :
o incluso:
volverá a imprimir :
fuente
Duplicatelíneas son inútiles, simplemente se pueden descartar.