Pregunta ¿Cómo puedo reemplazar una nueva línea (\ n) usando sed?


¿Cómo puedo reemplazar una nueva línea (\n) usando el comando sed?

Intenté sin éxito:

sed 's#\n# #g' file
sed 's#^$# #g' file

¿Cómo lo arreglo?


1125
2017-08-09 19:10


origen


Respuestas:


Usa esta solución con GNU sed:

sed ':a;N;$!ba;s/\n/ /g' file

Esto leerá todo el archivo en un bucle, luego reemplaza la (s) nueva (s) línea (s) con un espacio.

Explicación:

  1. Crea una etiqueta a través de :a.
  2. Agregue la línea actual y siguiente al espacio del patrón a través de N.
  3. Si estamos antes de la última línea, ramifíquese a la etiqueta creada $!ba ($! significa no hacerlo en la última línea, ya que debe haber una nueva línea final).
  4. Finalmente, la sustitución reemplaza cada línea nueva con un espacio en el espacio del patrón (que es el archivo completo).

Aquí hay una sintaxis compatible multiplataforma que funciona con BSD y OS X's sed (según @Benjie comentario)

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

1278
2017-08-09 20:26



Utilizar tr ¿en lugar?

tr '\n' ' ' < input_filename

o elimine los caracteres de nueva línea por completo:

tr -d '\n' < input.txt > output.txt

o si tienes la versión de GNU (con sus opciones largas)

tr --delete '\n' < input.txt > output.txt

1447
2017-08-09 19:16



Respuesta rápida:

sed ':a;N;$!ba;s/\n/ /g' file
  1. :un  crear una etiqueta 'a'
  2. norte  añada la siguiente línea al espacio del patrón
  3. ps  si no es la ultima linea, licenciado en Letras  rama (ir a) etiqueta 'a'
  4. s  sustituir, /\norte/  regex para nueva línea, / /  por un espacio, /gramo  partido global (tantas veces como sea posible)

sed recorrerá los pasos 1 a 3 hasta llegar a la última línea, haciendo que todas las líneas quepan en el espacio de patrones donde sed sustituya todos los \ n caracteres


Alternativas:

Todas las alternativas, a diferencia sed no será necesario llegar a la última línea para comenzar el proceso

con intento, lento

while read line; do printf "%s" "$line "; done < file

con Perl, sedcomo la velocidad

perl -p -e 's/\n/ /' file

con tr, más rápido que sed, puede reemplazar por un solo personaje

tr '\n' ' ' < file

con pegar, tr-como velocidad, puede reemplazar por un solo personaje

paste -s -d ' ' file

con awk, trcomo la velocidad

awk 1 ORS=' ' file

Otra alternativa como "echo $ (<archivo)" es lento, funciona solo en archivos pequeños y necesita procesar todo el archivo para comenzar el proceso.


Respuesta larga desde el sed FAQ 5.10:

5.10. ¿Por qué no puedo unir o eliminar una nueva línea usando \ n escape?
      ¿secuencia? ¿Por qué no puedo hacer coincidir 2 o más líneas con \ n?

\ N nunca coincidirá con la nueva línea al final de la línea porque el
   nueva línea siempre se quita antes de que la línea se coloque en el
   espacio de patrón. Para obtener 2 o más líneas en el espacio del patrón, use
   el comando 'N' o algo similar (como 'H; ...; g;').

Sed funciona así: sed lee una línea a la vez, corta el
   terminando nueva línea, coloca lo que queda en el espacio del patrón donde
   el script sed puede abordarlo o cambiarlo, y cuando el espacio del patrón
   se imprime, agrega una nueva línea a stdout (o a un archivo). Si el
   el espacio del patrón se borra total o parcialmente con 'd' o 'D', el
nueva línea es no agregado en tales casos. Por lo tanto, los guiones como

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

NUNCA funcionará, porque se elimina la nueva línea final antes de
   la línea se pone en el espacio del patrón. Para realizar las tareas anteriores,
   use uno de estos scripts en su lugar:

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

Dado que las versiones de sed distintas de GNU sed tienen límites para el tamaño de
   el buffer de patrón, la utilidad Unix 'tr' es preferible aquí.
   Si la última línea del archivo contiene una nueva línea, GNU sed agregará
   esa línea nueva a la salida pero borra todas las demás, mientras que tr
   eliminar todas las nuevas líneas.

Para hacer coincidir un bloque de dos o más líneas, hay 3 opciones básicas:
   (1) use el comando 'N' para agregar la siguiente línea al espacio del patrón;
   (2) use el comando 'H' al menos dos veces para agregar la línea actual
   al espacio Hold, y luego recuperar las líneas del espacio de espera
   con x, g o G; o (3) use rangos de direcciones (ver sección 3.3, arriba)
   para unir líneas entre dos direcciones especificadas.

Las opciones (1) y (2) pondrán \ n en el espacio del patrón, donde
   se pueden abordar como se desee ('s / ABC \ nXYZ / alphabet / g'). Un ejemplo
   de usar 'N' para eliminar un bloque de líneas aparece en la sección 4.13
   ("¿Cómo elimino un bloque de específico líneas consecutivas? "). Esto
   ejemplo puede ser modificado cambiando el comando de eliminar a algo
   else, como 'p' (imprimir), 'i' (insertar), 'c' (cambiar), 'a' (adjuntar),
   o 's' (sustituto).

La opción (3) no incluirá \ n en el espacio del patrón, pero hace
   coincide con un bloque de líneas consecutivas, por lo que puede ser que no lo haga
   incluso necesita el \ n para encontrar lo que está buscando. Desde GNU sed
   la versión 3.02.80 ahora admite esta sintaxis:

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

además del rango tradicional '/ from here /, / to there / {...}'
   direcciones, es posible evitar el uso de \ n por completo.


412
2017-10-08 14:55



Una alternativa awk más corta:

awk 1 ORS=' '

Explicación

Un programa awk está formado por reglas que consisten en bloques de código condicionales, es decir:

condition { code-block }

Si se omite el bloque de código, se utiliza el valor predeterminado: { print $0 }. Por lo tanto, la 1 se interpreta como una verdadera condición y print $0 se ejecuta para cada línea.

Cuando awk lee la entrada que divide en registros en función del valor de RS (Record Separator), que por defecto es una línea nueva, por lo tanto awk por defecto analizará la entrada en línea. La división también implica quitarse RS desde el registro de entrada.

Ahora, al imprimir un registro, ORS (Separador de registro de salida) se agrega al mismo (el valor predeterminado es nuevamente una nueva línea). Entonces al cambiar ORSa un espacio todas las líneas nuevas se cambian a espacios.


175
2018-02-13 12:12



gnu sed tiene una opción -z para registros separados nulos (líneas). Puedes simplemente llamar:

sed -z 's/\n/ /g'

91
2018-05-05 09:43



los Perl la versión funciona de la manera que esperabas

perl -i -p -e 's/\n//' file

Como se señaló en los comentarios, vale la pena señalar que esto se edita en su lugar. -i.bak le dará una copia de seguridad del archivo original antes del reemplazo en caso de que expresión regular no es tan inteligente como creías


75
2017-08-09 19:25



Quién necesita sed? Aquí está el bash camino:

cat test.txt |  while read line; do echo -n "$line "; done

40
2017-08-11 12:07



Para reemplazar todas las líneas nuevas con espacios usando awk, sin leer todo el archivo en la memoria:

awk '{printf "%s ", $0}' inputfile

Si quieres una nueva línea final:

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

Puedes usar un personaje que no sea el espacio:

awk '{printf "%s|", $0} END {printf "\n"}' inputfile

23
2018-03-30 06:41



Tres cosas.

  1. tr (o cat, etc.) no es absolutamente necesario. (ÑU) sed y (GNU) awk, cuando se combinan, puede hacer el 99.9% de cualquier procesamiento de texto que necesite.

  2. stream! = basado en línea. ed es un editor basado en línea. sed no es. Ver conferencia sed para más información sobre la diferencia. La mayoría de la gente confunde sed estar basado en la línea porque, por defecto, no es muy codicioso en su coincidencia de patrones para las coincidencias SIMPLE; por ejemplo, al realizar búsquedas de patrones y reemplazar por uno o dos caracteres, por defecto solo reemplaza en la primera coincidencia que encuentra ( a menos que se especifique lo contrario por el comando global). Ni siquiera habría un comando global si estuviera basado en línea en lugar de en STREAM, porque evaluaría solo líneas a la vez. Prueba correr ed; notarás la diferencia. ed es bastante útil si quieres iterar sobre líneas específicas (como en un bucle for), pero la mayoría de las veces solo querrás sed.

  3. Habiendo dicho eso,

    sed -e '{:q;N;s/\n/ /g;t q}' file
    

    funciona bien en GNU sed versión 4.2.1. El comando anterior reemplazará todas las líneas nuevas con espacios. Es feo y un poco engorroso escribir, pero funciona bien. los {}Se pueden omitir, ya que solo se incluyen por motivos de cordura.


20
2018-05-01 11:04



tr '\n' ' ' 

es el comando.

Simple y fácil de usar.


18
2018-04-13 19:01



La respuesta con: una etiqueta ...

¿Cómo puedo reemplazar una nueva línea (\ n) usando sed?

... no funciona en freebsd 7.2 en la línea de comandos:

(echo foo; barra de eco) | sed ': a; N; $! ba; s / \ n / / g'
sed: 1: ": a; N; $! ba; s / \ n / / g": etiqueta no utilizada 'a; N; $! ba; s / \ n / / g'
foo
bar

Pero lo hace si coloca el script sed en un archivo o usa -e para "compilar" el script sed ...

> (echo foo; barra de eco) | sed-e: a -e N -e '$! ba' -e 's / \ n / / g'
foo bar

o ...

> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof

> (echo foo; echo bar) | sed -f x.sed
foo bar

Quizás el sed en OS X es similar.


12
2017-09-24 22:26