2012-05-18 15 views
5

Tengo dos archivos con líneas ordenadas. Un archivo (B) es un subconjunto del otro archivo (A). Me gustaría encontrar todas las líneas en A que NO estén en B. Idealmente, me gustaría crear un archivo (C) que contenga estas líneas. ¿Es esto posible en Unix? Estoy buscando un comando de una línea para hacer esto en lugar de escribir un guión. Miré los comandos join y diff, pero no pude encontrar una opción de comando para hacer esto. Gracias por la ayuda.¿Cómo encontrar el conjunto - Subconjunto de dos archivos desde la línea de comando?

Respuesta

12

Esto suprimirá líneas comunes:

comm -3 a b 
+1

Y en caso de que le gustaría encontrar alguna de las líneas comunes en ambos archivos, puede usar 'comm -12 ab' – voithos

+0

Para crear un tercer archivo c se podría usar, por supuesto,' comm -3 ab> c' – 0x4a6f4672

5

¿Qué tal esto:

grep -v -f B A > C 
3

Usted puede hacer esto con diff también. Diff (a diferencia de @ johlo respuesta grep) se preocupa por fin, funciona en archivos sin ordenar (a diferencia de @ johnshen64 respuesta Comm):

$ cat a 
a 
b 
c 
d 
e 
$ cat b 
a 
b 
f 
d 
e 
$ diff -dbU0 a b 
--- a 2012-05-18 16:02:30.603386016 -0400 
+++ b 2012-05-18 16:02:45.547817122 -0400 
@@ -3 +3 @@ 
-c 
+f 

esta manera puede utilizar una tubería para conseguir el fin sólo las líneas -considerando omitidas:

$ diff -dbU0 a b | tail -n +4 | grep ^- | cut -c2- 
c 
0

Awk solución

archivos de entrada

un

aaa 
bbb 
ccc 

b

ccc 
ddd 
eel 

Código

awk ' NR==FNR { A[$0]=1; next; } 
{ if ($0 in A) { A[$0]=0; } } 
END { for (k in A) { if (A[k]==1) { print k; } } } ' a b > c 

c (Archivo de salida)

bbb 
aaa 
+0

OP solicitó específicamente una solución que no sea de script. Dado, has puesto el script en la línea de comando, pero ... – derobert

1

Este comando join hará lo que preguntas:

join -v 1 fileA fileB > fileC 

Demostración:

$ cat fileA 
a 
c 
d 
g 
h 
t 
u 
v 
z 
$ cat fileB 
a 
d 
g 
t 
u 
z 
$ join -v 1 fileA fileB 
c 
h 
v 

Esto supone que los archivos ordenados como ha afirmado en su pregunta. Para los archivos sin ordenar:

join -v 1 <(sort fileA) <(sort fileB) 
Cuestiones relacionadas