2012-01-13 26 views
8

Infile1:Bash unirse comando

1 a 
3 c 
4 d 
6 f 

Infile2:

1 a 
2 b 
5 e 
6 f 
7 g 
8 h 

¿Cómo me uno a estos archivos con el UNIX sumo comando para obtener este resultado:

1 aa 
2 b 
3 c 
4 d 
5 e 
6 ff 
7 g 
8 h 

Dogbanes responden trabajados pero ... cuando aplico respuestas dogbanes en este archivo:

27 27 
28 22 
29 37 
30 15 
31 21 
32 13 
33 18 
34 24 

y esto:

27 7 
28 13 
29 6 
30 12 
31 30 
32 5 
33 10 
34 28 

no se unen:

27 27 
27 7 
28 13 
28 22 
29 37 
29 6 
30 12 
30 15 
31 21 
31 30 
32 13 
32 5 
33 10 
33 18 
34 24 
34 28 

El segundo escenario es delimitado por tabuladores, así que utiliza -t \t

Respuesta

11

Primera sort ambos archivos. Luego use join para unir el primer campo de ambos archivos. También necesita canalizar la salida a través de sed si desea eliminar el espacio y así convertir a a en aa. Esto se muestra a continuación:

$ join -t " " -1 1 -2 1 -a 1 -a 2 <(sort file1) <(sort file2) | sed 's/ \([a-z]\)/\1/g' 
1 aa 
2 b 
3 c 
4 d 
5 e 
6 ff 
7 g 
8 h 
11

Funciona para mí (casi). Debe especificar -t $'\t' para el carácter de tabulación, no solo -t \t. Bash no interpreta \t a menos que en $'' comillas.

join -t $'\t' -o 1.2,2.2 <(echo $'27\t27 
28\t22 
29\t37 
30\t15 
31\t21 
32\t13 
33\t18 
34\t24' | sort) <(echo $'27\t7 
28\t13 
29\t6 
30\t12 
31\t30 
32\t5 
33\t10 
34\t28' | sort) 
27  7 
22  13 
37  6 
15  12 
21  30 
13  5 
18  10 
24  28 
4

esto debería funcionar para sus dos casos:

salida
awk 'NR==FNR{a[$1]=$2;next;} {a[$1]=($1 in a)?a[$1]$2:$2}END{for(x in a)print x,a[x]}' f1 f2|sort 

para el caso de una:

salida
1 aa 
2 b 
3 c 
4 d 
5 e 
6 ff 
7 g 
8 h 

para el caso de dos:

27 277 
28 2213 
29 376 
30 1512 
31 2130 
32 135 
33 1810 
34 2428 
+0

bien hecho. Me gustó el uso de 'ternary operator' en lugar de' if-else' +1 :) –

Cuestiones relacionadas