bash / sed / awk / etc eliminar cualquier otra línea nueva


39

un comando bash genera esto:

Runtime Name: vmhba2:C0:T3:L14
Group State: active
Runtime Name: vmhba3:C0:T0:L14
Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14
Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14
Group State: active
Runtime Name: vmhba2:C0:T2:L14
Group State: active

Me gustaría canalizarlo a algo para que se vea así:

Runtime Name: vmhba2:C0:T1:L14 Group State: active 
Runtime Name: vmhba3:C0:T3:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T2:L14 Group State: active
[...]

es decir, eliminar cualquier otra línea nueva

Lo intenté ... |tr "\nGroup" " "pero eliminó todas las líneas nuevas y se comió algunas otras letras también. Gracias


2
trestá completamente basado en caracteres: solicitó a tr que elimine las nuevas líneas y todas las 'G', 'r', 'o', 'u' y 'p'.
Glenn Jackman

Respuestas:


80

no puedo probar en este momento, pero

... | paste - - 

Deberías hacerlo


55
+1 - funciona y es elegante. (Pone una pestaña entre las líneas; paste -d ' ' - -agregará un espacio en su lugar si es necesario)
cyberx86

44
¿Podría explicar cómo funciona el comando? ¿Por qué hay dos -? Gracias
bbaja42

77
pastese utiliza para concatenar correspondientes líneas de un fichero: paste file1 file2 file3 .... Si uno de los argumentos del "archivo" es "-", las líneas se leen desde la entrada estándar. Si hay 2 argumentos "-", pegar toma 2 líneas de stdin. Y así. Ver la página del manual .
Glenn Jackman

10

Una posibilidad es:

awk 'ORS=NR%2?" ":"\n"'

Si el número de línea es divisible por 2, termine con una nueva línea, de lo contrario, termine con un espacio.

(Probado en: CentOS 6, GNU Awk 3.1.7)

Usando sed (ver explicación ):

sed ':a;N;$!ba;s/\nGroup/ Group/g'

Otras lecturas:


8

Si desea usar sed, no hay razón para leer todo el archivo en la memoria. Puede fusionar cualquier otra línea como esta:

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

Use cualquier personaje que desee en lugar del espacio.

Aquí hay otra forma de usar awk:

awk '{printf "%s", $0; if (getline) print " " $0; else printf "\n"}' inputfile

El if/elsemaneja el caso donde hay un número impar de líneas en el archivo. Sin ella, la última línea impar se imprime dos veces. De lo contrario, para comparar, podría hacer:

awk '{printf "%s", $0; getline; print " " $0}'

1
Un comentario tardío: 1) utilice siempre un especificador de formato para printf en caso de que la cadena tenga signos de porcentaje, 2) para evitar la última línea duplicada, configure $ 0 en "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman

3

La forma más idiomática de hacerlo awkes la siguiente:

awk 'ORS=NR%2?FS:RS' file

Produce:

Runtime Name: vmhba2:C0:T3:L14 Group State: active
Runtime Name: vmhba3:C0:T0:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14 Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14 Group State: active
Runtime Name: vmhba2:C0:T2:L14 Group State: active

Para explicarlo, necesitamos definir cada una de las variables integradas:

  • RSseparador de registros El valor predeterminado es \n(nueva línea).
  • ORSseparador de registro de salida. El valor predeterminado es \n(nueva línea).
  • FSseparador de campo El valor predeterminado es (espacio).
  • NR Número de registro.

Como el separador de registros predeterminado es la nueva línea, un registro es, por defecto, una línea.

NR%2es el módulo de NR/2, por lo que será 0o 1. 0para líneas pares y 1para líneas impares.

var=condition?condition_if_true:condition_if_false es el operador ternario.

Todos juntos, diciendo ORS=NR%2?FS:RSque estamos definiendo el separador de registro de salida:

  • si el número de registros está en el formulario 2k + 1, es decir, en líneas pares, entonces los separadores de registros de salida se establecen en FS, es decir, un espacio.
  • si el número de registro está en el formulario 2k, es decir, en líneas impares, entonces los separadores de registros de salida se establecen en RS, es decir, una nueva línea.

De esta manera, las líneas impares terminan con un espacio, que luego se une con la siguiente línea. Después de esa línea, se imprime una nueva línea.

Más información en Idiomatic awk .


2

Esto funciona para mí en Linux:

... | tr "\\n" " "

Esto reemplaza un espacio vacío para un carácter de nueva línea; que debe escapar del carácter de nueva línea para que las cosas funcionen correctamente.


Esto elimina todos los de nueva línea, no todos los otros de nueva línea.
Trenton

2

En bash:

... | while read l1; do read l2; echo "$l1 $l2"; done

1

Si Perl es una opción:

perl -pe 's/\n/ / if $. % 2 == 1' file

s/\n/ /reemplaza nueva línea con espacio
$.es el número de línea


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.