Combina líneas alternativas de dos archivos

9

Archivo1:

.tid.setnr := 1123 
.tid.setnr := 3345 
.tid.setnr := 5431
.tid.setnr := 89323

Archivo2:

.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60

Archivo de salida:

.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
pmaipmui
fuente
2
Por favor siempre mencione su sistema operativo. Muchas de las herramientas estándar se comportan de manera diferente en los diferentes sistemas operativos, por lo que necesitamos saber qué está utilizando.
terdon

Respuestas:

23

Utilizando paste:

paste -d \\n file2 file1
Stephen Kitt
fuente
5

Otra solución awk:

awk '{print; getline < "file1"; print}' file2
Glenn Jackman
fuente
5

La pastesolución es la más portátil y más eficiente. Solo menciono esta alternativa en caso de que prefiera su comportamiento en el caso de que los dos archivos no tengan el mismo número de líneas:

Con GNU sed:

sed Rfile1 file2

Si file1tiene menos líneas que file2, entonces cuando file1está agotado, sedno generará nada para él (a diferencia de las líneas vacías para paste).

Si file1tiene más líneas que file2, entonces esas líneas adicionales se descartarán (en lugar de imprimir líneas vacías para file2con paste).

$ paste a b
1       a
2       b
3
4
$ paste -d \\n a b
1
a
2
b
3

4

$ sed Rb a
1
a
2
b
3
4
$ sed Ra b
a
1
b
2
Stéphane Chazelas
fuente
4

Uso de awk( gawk, nawk, mawk):

awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1 > outputfile
  • NR==FNR {x[FNR]=$0;next}: NR==FNRsolo coincide si el número de registro actual es igual al número de registro del archivo actual (por lo tanto, solo coincide mientras se procesa el primer archivo): almacena el registro procesado actualmente en la matriz xen un índice igual al número de registro del archivo actual y omite el registro actual
  • {print x[FNR]"\n"$0}: imprime el contenido de la matriz xen un índice igual al número de registro del archivo actual seguido de una nueva línea y del contenido del registro actual
~/tmp$ cat file1
.tid.setnr := 1123
.tid.setnr := 3345
.tid.setnr := 5431
.tid.setnr := 89323
~/tmp$ cat file2
.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60
~/tmp$ awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1
.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
kos
fuente
Está dando la salida, pero no es exactamente lo mismo que quería. Las líneas tid.info vienen después de las líneas tid.setnr en mi archivo de salida.
pmaipmui
@Nainita Eso es lo que estás mostrando en tu salida de ejemplo.
kos
@Nainita De todos modos, para cambiar el orden de la salida, simplemente puede cambiar file1y file2en el comando.
kos
Sí ... he hecho lo mismo pero estaba imprimiendo exactamente como antes. después de imprimir tid.setnr, fue tid.info.
pmaipmui
1
@mikeserv Sin embargo, desde que lo hice, lo intenté mawktambién, y también funciona. De todos modos, siendo razonable, no puedo ver por qué no debería funcionar al revés (es decir, simplemente cambiando los archivos). No es que awkle importe la entrada, las líneas son líneas. Si algo no fuera compatible con su versión, se habría roto la primera vez. Más fácilmente, simplemente OP cometió un error al cambiar los archivos de entrada en los argumentos.
kos
-1

La solución más fácil se da a continuación.

cat file1 >> file2

o

cat file2 >> file1
sachin
fuente
1
Sachin, lee la pregunta nuevamente; esto agrega el contenido de un archivo al contenido de otro archivo. No combina los archivos alternando las líneas (por lo tanto, una línea a partir de file1una línea file2y así sucesivamente ...)
don_crissti