una - Intersección de dos listas en Bash
signo/en bash (6)
Intento escribir un script simple que enumere los contenidos encontrados en dos listas. Para simplificar, usemos ls como ejemplo. Imagina que "uno" y "dos" son directorios.
one=`ls one` two=`ls two` intersection $one $two
Todavía estoy bastante verde en bash, así que no dudes en corregir cómo lo estoy haciendo. Solo necesito un comando que imprima todos los archivos en "uno" y "dos". Deben existir en ambos. Puede llamar a esto la "intersección" entre "uno" y "dos".
Hay otra pregunta de "Intersección de matriz en bash", que está marcada como un duplicado de esto. No es lo mismo, en mi opinión, ya que esa pregunta habla de comparar dos arreglos bash, mientras que esta pregunta se centra en los archivos bash. Una respuesta de una línea a la otra pregunta, que ahora está cerrada, es la siguiente:
# List1=( 0 1 2 3 4 6 7 8 9 10 11 12)
# List2=( 1 2 3 5 6 8 9 11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "/n"| sort) <(echo ${List2[*]} | tr " " "/n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11
La utilidad de comunicación tiene un orden alfanumérico, mientras que la "Intersección de matriz en bash" responde con números; de ahí el uso de "ordenar" y "ordenar -g".
Una alternativa menos eficiente (que comm):
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
Unirse es otra buena opción dependiendo de la entrada y salida deseada
join -j1 -a1 <(ls 1) <(ls 2)
Use el comando comm
:
ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list
"ordenar" no es realmente necesario, pero siempre lo incluyo antes de usar "comm" por si acaso.
Solución con comm
comm
es genial, pero de hecho necesita trabajar con la lista ordenada. Y, afortunadamente, aquí usamos ls
que desde ls
página de hombre de Bash
Ordene las entradas alfabéticamente si no hay ninguna -cftuSUX ni -sort.
comm -12 <(ls one) <(ls two)
Alternativa con el sort
Intersección de dos listas:
sort <(ls one) <(ls two) | uniq -d
diferencia simétrica de dos listas:
sort <(ls one) <(ls two) | uniq -u
Prima
Juega con ello ;)
cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
comm -12 <(ls 1) <(ls 2)