2010-10-16 9 views
5

Tengo 2 archivos, el primero contiene lo siguiente:AWK/BASH: ¿cómo hacer coincidir un campo en un archivo de un campo en otro?

... 
John Allen Smith II 16 555-555-5555 10/24/2010 
John Allen Smith II 3 555-555-5555 10/24/2010 
John Allen Smith II 17 555-555-5555 10/24/2010 
John Doe 16 555-555-5555 10/24/2010 
Jane Smith 16 555-555-5555 9/16/2010 
Jane Smith 00 555-555-5555 10/24/2010 
... 

y el segundo archivo es una lista de nombres de por lo ...

... 
John Allen Smith II 
John Doe 
Jane Smith 
... 

¿Es posible usar awk (u otra fiesta comando) para imprimir las líneas en el primer archivo que coinciden con cualquier nombre en el segundo archivo (los nombres pueden repetirse en el primer archivo)

¿Bonificación? ¿Hay alguna manera fácil de eliminar esas líneas repetidas/duplicadas en el primer archivo?

Muchas gracias,

Tomek

+0

Si hay 2 líneas iguales, se queda una. ¿Es esa tu definición de "eliminar" líneas duplicadas? – ghostdog74

Respuesta

3

awk

#! /bin/bash 
awk 'FNR==NR{!a[$0]++;next }{ b[$0]++ } 
END{ 
    for(i in a){ 
    for(k in b){ 
     if (a[i]==1 && i ~ k) { print i } 
    } 
    } 
}' file1 file2 
1

Se puede utilizar como grep:

grep -f file2 file1 # file2 is the file with the names. 

La opción de -fgrep obtiene el patrón a buscar desde el archivo.

para eliminar las líneas duplicado exacto de la salida se puede utilizar sort como:

grep -f file2 file1 | sort -u 
+0

Intenté usar el comando pero obtuve lo siguiente, "grep: Incomparable [o [^", luego intenté usar -F para forzar pero no hubo salida? ¿Este comando usa todo el archivo2 en un patrón de búsqueda para probar y hacer coincidir con el archivo1? – Tomek

+0

Especifiqué incorrectamente el indicador -F (sustituí -f por -F) para que funcionara el comando final grep -f archivo2 -F archivo1. Gracias por la ayuda. – Tomek

+0

para el único, estaba buscando eliminar las líneas del archivo1 que solo tienen los nombres repetidos (las otras columnas tienen datos diferentes) – Tomek

1

la expansión en la respuesta de codaddict:

grep -f file2 file1 | sort | uniq 

esto eliminará las líneas que son exactamente iguales, pero el efecto secundario (que puede ser no deseado) es que su dat afile ahora será ordenado. También requiere que las líneas sean exactamente iguales, lo que no es el caso en sus datos de ejemplo. Los nombres son los mismos, pero los datos después de esos mismos nombres son diferentes. uniq puede tomar una opción de recuento de campo o de caracteres, pero esto no funcionará en sus datos porque sus nombres tienen una longitud variable y una cantidad variable de campos. Si conoces a los campos de datos son siempre los últimos 3 campos en una línea, entonces usted puede hacer esto:

grep -f file2 file1 | sort | rev | uniq -f 3 | rev 

su salida será sólo una de cada nombre, pero ¿cuál? el más bajo lexicográficamente porque fue ordenado (sort es necesario para que uniq funcione correctamente). Si no desea ordenarlo primero, o necesita tener cuidado con cuáles de las líneas se descartan, entonces una solución awk o perl o ruby ​​o python probablemente funcionará mejor utilizando matrices asociativas.

+0

Sí, ese es exactamente mi problema. Los nombres pueden ser de longitud variable y los datos después del nombre son diferentes. Solo estoy buscando la primera aparición de decir John Allen Smith II. Buscaré en algunas matrices asociativas con awk. Gracias por la info. – Tomek

Cuestiones relacionadas