2010-10-25 37 views
57

¿Cuál es la manera más fácil/más rápida de intercalar las líneas de dos (o más) archivos de texto? Ejemplo:Cómo intercalar líneas desde dos archivos de texto

Archivo 1:

line1.1 
line1.2 
line1.3 

Archivo 2:

line2.1 
line2.2 
line2.3 

Intercalado:

line1.1 
line2.1 
line1.2 
line2.2 
line1.3 
line2.3 

Claro que es fácil escribir un pequeño script en Perl que los abre a ambos y hace la tarea. Pero me preguntaba si es posible salirse con la suya con menos códigos, tal vez con un solo trazador usando las herramientas de Unix.

Respuesta

110
paste -d '\n' file1 file2 
+2

N.B. en algunas plataformas, 'pegar' es bastante limitado, p. en Solaris puede tener como máximo 12 archivos de entrada y las líneas de salida están limitadas a 511 caracteres. – user667489

-1
cat file1 file2 |sort -t. -k 2.1 

Aquí su especificó que la separater es "" y que estamos ordenando el primer personaje del segundo campo.

+0

No entiendo cómo funciona esto.Por ejemplo, no hay dos puntos en la entrada de clasificación? ¿Puedes explicarme mas? – Frank

+0

mi mal, cambié el ':' a '.' es solo el separador; si no está especificado, el ordenamiento se usa en blanco para separar los campos. 'man sort' para más información. – Sujoy

+7

Esta respuesta asume que la entrada realmente toma la forma literal descrita en la pregunta. Creo que se suponía que era ilustrativo. Sería posible transformar cada archivo de entrada de esa manera, pero sería mucho más pasa a través de los datos. La respuesta de codaddict es mejor. – Novelocrat

1

Aquí hay una forma de GUI para hacerlo: Pegarlos en dos columnas en una hoja de cálculo, copiar todas las celdas, luego usar expresiones regulares para reemplazar las pestañas con líneas nuevas.

6

Aquí es una solución utilizando awk:

awk '{print; if(getline < "file2") print}' file1 

produce esta salida:

line 1 from file1 
line 1 from file2 
line 2 from file1 
line 2 from file2 
...etc 

Usando awk puede ser útil si desea agregar algo de formato extra a la salida, por ejemplo, si desea para etiquetar cada línea según el archivo del que proviene:

awk '{print "1: "$0; if(getline < "file2") print "2: "$0}' file1 

produce esta salida:

1: line 1 from file1 
2: line 1 from file2 
1: line 2 from file1 
2: line 2 from file2 
...etc 

Nota: este código se supone que fichero1 es mayor que o igual a la longitud file2.

Si fichero1 contiene más líneas que fichero2 y que desea líneas en blanco de salida para fichero2 después de que termine, añadir una cláusula else a la prueba getline:

awk '{print; if(getline < "file2") print; else print ""}' file1 

o

awk '{print "1: "$0; if(getline < "file2") print "2: "$0; else print"2: "}' file1 
1

@Sujoy's answer puntos en una dirección útil. Puede añadir números de línea, ordenar y despojar a los números de línea:

(cat -n file1 ; cat -n file2) | sort -n | cut -f2- 

Nota (de interés para mí) esto necesita un poco más de trabajo para conseguir el orden correcto si en lugar de archivos estáticos se utiliza la salida de los comandos que puede correr más lento o más rápido que el otro. En ese caso, debe agregar/ordenar/eliminar otra etiqueta además de los números de línea:

(cat -n <(command1...) | sed 's/^/1\t/' ; cat -n <(command2...) | sed 's/^/2\t/' ; cat -n <(command3) | sed 's/^/3\t/') \ 
    | sort -n | cut -f2- | sort -n | cut -f2- 
Cuestiones relacionadas