2011-12-17 20 views
12

Necesito mover los contenidos de cada segunda línea hasta la línea superior de modo que los datos de la línea 2 estén junto a los de la línea 1, ya sea en coma o en espacios separados.¿Cómo puedo unir pares de líneas consecutivas en un archivo grande (1 millón de líneas) utilizando vim, sed u otra herramienta similar?

de entrada:

line1 
line2 
line3 
line4 

Salida:

line1 line2 
line3 line4 

que he estado haciendo en vim con una grabación sencilla pero vim parece bloquearse cuando se lo cuento a hacerlo 100 000 veces. ¿Estoy pensando que quizás Sed sería una buena alternativa pero no estoy seguro de cómo hacer lo que quiero o tal vez haya una mejor opción?

Cada línea contiene solamente 1 valor numérico, sólo tengo un millón de líneas ...

+1

FORMATEE su pregunta, y nos muestran entrada adecuada y salida esperada. –

Respuesta

14

Si he entendido bien, que tienen:

y que desea:

line1<SEP>line2 
line3<SEP>line4 

entonces usted puede hacerlo fácilmente con (g)awk de esta manera:

awk 'NR % 2 == 1 { o=$0 ; next } { print o "<sep>" $0 }' INPUTFILE 

See it in action here.

actualización: si el número de líneas es impar, lo anterior se omita la última línea (como Martin Stettner señaló) por lo que este no:

awk 'NR % 2 == 1 { o=$0 ; next } { print o "<sep>" $0 } END { if (NR % 2 == 1) { print o } }' INPUTFILE 

HTH

+1

¿No omitiría este script la última línea en caso de que tenga un número impar de líneas? – MartinStettner

+0

@MartinStettner tienes razón. Actualizando la solución. –

7

intente esto:

sed -rn 'N;s/\n/ /;p' yourFile 

prueba con SEC:

kent$ seq 10 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

kent$ seq 10|sed -rn 'N;s/\n/ /;p' 
1 2 
3 4 
5 6 
7 8 
9 10 

awk trabaja demasiado:

awk 'NR%2{printf $0" ";next;}1' yourFile 

prueba

kent$ seq 10|awk 'NR%2{printf $0" ";next;}1' 
1 2 
3 4 
5 6 
7 8 
9 10 
6

Esto podría funcionar para usted:

sed 'N;s/\n/ /' file 

O

cat file | paste -d' ' - - 
6

Bueno, su ejemplo es esto en Vim.

:g/^/+t.|-j

Pero entonces ¿qué pasa con la última línea?

¿O era esto?

:g/^/j 

También podría estar interesado en este script de Vim, lo que hace que se trata de archivos de gran tamaño más fácil.

http://www.vim.org/scripts/script.php?script_id=1506

+0

Hola, ¡¡sabía que tenía que haber una manera mejor de lo que estaba intentando !! :) Gracias por la gran cantidad de opciones, ¡g/^/j fue el más simple y hace el trabajo genial! – janeruthh

+0

Editado el OP siguiendo la aclaración anterior anterior. La primera sugerencia en mi respuesta ahora puede ser ignorada. – 1983

+0

¡Excelente consejo de Vim! En mi caso, no era el archivo completo, entonces puede usar una Selección Visual ': '<,'> g/^/j' o entre la _a marca_ y la línea actual':' a, .g/^/j' para limitar la unión a mi rango de interés. ¡Lo hace 773 veces manualmente! – ddevienne

2
$ seq 10 | sed '2~2G' | awk -v RS='' '{$1=$1; print}' 
1 2 
3 4 
5 6 
7 8 
9 10 

$ paste -d' ' <(sed -n 'p;n' num.txt) <(sed -n 'n;p' num.txt) 
1 2 
3 4 
5 6 
7 8 
9 10 

$ echo -e 'g/^/,+1j\n%p' | ex num.txt 
1 2 
3 4 
5 6 
7 8 
9 10 

$ seq 10 | awk 'NR%2{printf("%s ", $0); next}1' 
1 2 
3 4 
5 6 
7 8 
9 10 

$ seq 10 | sed 'N;s/\n/ /' 
1 2 
3 4 
5 6 
7 8 
9 10 

nota:$ seq 10 >num.txt

+0

¿Qué tal 'perl'? 'seq 10 | perl -pe '$ a ++% 2 || s/\ n// '' – Sorpigal

5

El comando pasta se puede hacer esto. Su opción "-s" unirá líneas consecutivas; y la opción "-d" especifica una lista de caracteres para usar como delimitadores, repitiéndolos cíclicamente. Se unen por primera vez con un espacio, a continuación, con un salto de línea, y repetir:

seq 10 | paste -sd" \n" - 
0
seq 10 | awk 'ORS=NR%2?FS:RS' 

Esta solución utiliza "operador ternario" para establecer ORS

ORS= ....... output register separator (will receive =) 
NR%2 ....... test if it has division remainder of Number of Register by 2 
?FS:RS ..... FS = "space" RS = "\n" (newline) 
Cuestiones relacionadas