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
sortcongrepes 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 tuawkel código abordaría este caso de uso. - @Josh sí, simplemente cambie
$0por$NdondeNes 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