Quiero realizar lo que algunos software de análisis de datos llaman anti-unión: eliminar de una lista esas líneas líneas coincidentes en otra lista. Aquí hay algunos datos de juguetes y el resultado esperado:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Comentarios
- Relacionando unix.stackexchange.com/q/11343/117549
- ¿Responde esto a su pregunta? ¿Existe una herramienta para obtener las líneas en un archivo que no están en otro?
- @Muru, sí, esa publicación proporciona las soluciones. presentado en la respuesta de Terdon '. Sin embargo, cuando buscaba " bash anti-join " (la terminología que asocio con este tipo de proceso), no ' t encontrar algo útil. Mi OP (que otros han editado) declaró que mi propósito explícito al hacer esta pregunta era asociar el término " anti-join " con las soluciones, de modo que la búsqueda de este término produce estas soluciones. Gracias.
Respuesta
No usaría join
para esto porque join
requiere que se ordenen las entradas, lo cual es una complicación innecesaria para un trabajo tan simple. En su lugar, podría usar grep
:
$ grep -vxFf list2 list1 a b
O awk
:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Si los archivos ya están ordenados, una alternativa a join -v 1
sería comm -23
$ comm -23 list1 list2 a b
Comentarios
- Evitar
sort
congrep
es genial por los datos de juguetes que proporcioné. ¡Gracias! En el mundo real, mi archivo1 a menudo tiene varias columnas de datos, una de las cuales se usa para la combinación. Una versión modificada de tuawk
el código abordaría este caso de uso. - @Josh sí, simplemente cambie
$0
por$N
dondeN
es el número de campo al que se está uniendo. - Esto funciona incluso si los números de columna en file1 y file2 son diferentes: como awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 list1; Es bastante habitual que el archivo de etiquetas tenga un formato diferente al de los datos principales.
Respuesta
Una forma de hacer esto con la utilidad join
es:
$ join -v 1 list1 list2 a b