2011-02-11 14 views
5

Me gustaría fusionar dos archivos de acuerdo con el contenido de sus 2 columnas.unix: fusiona 2 archivos usando 2das columnas

File 1:

"4742" "209220_at"  2.60700394801826 
"104" "209396_s_at" 2.60651442103297 
"749" "202409_at"  2.59424724783704 
"4168" "209875_s_at" 2.58773204877464 
"3973" "1431_at"  2.52832098784342 
"1826" "207201_s_at" 2.41685345240968 

Archivo2:

"653" "1431_at"  2.14595534191867 
"1109" "207201_s_at" 2.13777517447307 
"353" "212531_at"  2.12706340284672 
"381" "206535_at"  2.11456707231618 
"1846" "204534_at"  2.10919474441178 

tener en el extremo:

"3973" "1431_at"  2.52832098784342 "653" "1431_at"  2.14595534191867 
"1826" "207201_s_at" 2.41685345240968 "1109" "207201_s_at" 2.13777517447307 

He tratado comm, diff, algunos oscura awk de una sola línea sin cualquier exito Cualquier ayuda muy apreciada. Ben

Respuesta

2
awk ' 
    # store the first file, indexed by col2 
    NR==FNR {f1[$2] = $0; next} 
    # output only if file1 contains file2's col2 
    ($2 in f1) {print f1[$2], $0} 
' file1 file2 
+2

tenga en cuenta que esto almacenará todo el archivo1 en la memoria, por lo que es posible que desee colocar el archivo más pequeño como 'archivo1' –

0

Si los archivos son pequeños, escriba un programa en un lenguaje de scripting (Perl, Python y Ruby son todas buenas elecciones) que lee el primero en un hash cuyas claves son la segunda columna, luego lea el segundo archivo y usa búsquedas hash para encontrar qué (si hay algo) se puede unir.

Si los archivos son grandes, para cada archivo cambie la primera y la segunda columna, páselos a través de la utilidad de ordenamiento unix y luego en una combinación de lenguaje de scripting (más columna reordena) los dos archivos ordenados.

5

Puede hacerlo con una combinación de los comandos sort y join. El enfoque directo es

join -j2 <(sort -k2 file1) <(sort -k2 file2) 

pero eso se muestra de forma ligeramente diferente a lo que está buscando. Esto demuestra lo común se unen campo y luego los campos restantes de cada archivo

"1431_at" "3973" 2.52832098784342 "653" 2.14595534191867 
"207201_s_at" "1826" 2.41685345240968 "1109" 2.13777517447307 

Si necesita el formato tal y como se mostró, entonces usted tendría que decirle join a la salida de esa manera

join -o 1.1,1.2,1.3,2.1,2.2,2.3 -j2 <(sort -k2 file1) <(sort -k2 file2) 

donde -o acepta una lista de especificadores FILENUM.FIELDNUM.

Tenga en cuenta que la sintaxis <() que estoy usando no es POSIX sh, por lo que debe ordenar a un archivo temporal si necesita la sintaxis POSIX sh.

+0

si está utilizando ciertas versiones de fiesta, también se puede escribir: 'unirse a -j2 <(archivo tipo -k2 {1,2})' –

+0

Excepto que no proporciona unirse a dos distintos conjuntos de entrada. – jamessan

0
awk 'FNR==NR{a[$2]=$0} NR>FNR && ($2 in a){ print $0,a[$2] } ' file2 file1 
Cuestiones relacionadas