Reemplazar \ n por una nueva línea en sed portátil

23

Estoy tan confundido con GNU sed, POSIX sedy sedla gran cantidad de opciones de BSD . ¿Cómo reemplazo literal \ncon el carácter de nueva línea usando estos tres sedtipos?

Avinash Raj
fuente
Tienen muchas cosas diferentes, ¿qué parte quieres saber?
Cuonglm
@Gnouc, creo que ahora está claro.
Avinash Raj
1
¿Has echado un vistazo a esta pregunta ?
groxxda
2
¿Cómo quieres que suceda en la entrada foo\\nbaro foo\\\nbar?
Gilles 'SO- deja de ser malvado'
simple, foo \\ en la siguiente línea sería bar.
Avinash Raj

Respuestas:

30
sed 's/\\n/\
/g'

Observe la barra invertida justo antes de presionar la tecla de retorno en la cadena de reemplazo.

unxnut
fuente
¿Esto funciona para todo tipo de sed?
Avinash Raj
Creo que debería; Probé solo en Linux usando la versión gnu.
unxnut
11
@AvinashRaj. Eso es POSIX y funcionó con el sedcomando original en Unix v7 en 1979. El único lugar donde eso podría no funcionar sería implementaciones no POSIX despojadas, sedcomo algunas despojadas basadas en busybox. Eso no funcionará en csh pero es un problema de csh.
Stéphane Chazelas
Como \\nse usa en la parte de búsqueda, ¿por qué no usar \nen el reemplazo? lo primero parece implicar que lo último existe. es decir. ¿Por qué no esto$ echo '1\n2'|sed 's/\\n/\n/g'
En este caso, \nes un literal, lo que implica que aparece como los dos caracteres: una barra diagonal inversa seguida de n, y no como un solo carácter de nueva línea. Por lo tanto, dos barras invertidas para hacer backslash un literal y luegon
unxnut
9

Como ya tiene su sedrespuesta portátil , solo mencionaré que sedrara vez es la mejor herramienta si necesita manipular nuevas líneas. Perl es casi tan portátil como sed, está instalado de forma predeterminada en la mayoría de los sistemas * nix y puede manejar esto muy fácilmente:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

Otra opción muy portátil es awk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

En Solaris, recuerde usar el awk estándar en / usr / xpg4 / bin, el que está en / bin es histórico y no debe usarse para nuevos scripts.

terdon
fuente
Yo diría que awktiene problemas de portabilidad similares (¿Es mi awkviejo awk, nawko gawk?). En realidad, la versión en mis cajas de Solaris carece gsub(). Mi voto aquí es por Perl (se perl -nlawe '...'aproxima al comportamiento automático de awk).
arielCo
2
@arielCo: para la awkportabilidad, quédese con una versión awkque sea compatible con POSIX y solo use esas funciones y debería estar bien. En Solaris encontrará uno como /usr/xpg4/bin/awk.
Scrutinizer
@terdon ¿qué tal esto echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'?
Avinash Raj
@arielCo en realidad, awk es más portátil que perl. Mi segundo enfoque awk que no usa gsub()debería funcionar en casi todas partes. Incluso busybox tiene un awk.
terdon
1
gsub () es POSIX (gsub, se agregó en SVR3.1, POSIX awk se basa en SVR4 con algunas adiciones; consulte el manual de gawk para obtener más información), gensub () es la extensión GNU. El awk original todavía se encontraba como / bin / awk en Solaris, no admitía el soporte gsub (), pero tampoco admitía un FS de caracteres múltiples.
Stéphane Chazelas
1

Si Holdspace está vacío, también puede hacer:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

... pero la respuesta de uxnut ya es más rápida y más simple, por lo que puedes tomarla como quieras.

Otra posibilidad extraña:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

Pero tenga cuidado, ^ eso traduce todos los \escapes de barra invertida de estilo C estándar , como \backspace y \return \00y octals y lo que sea que tenga.

mikeserv
fuente
0

Con gnu sedlo siguiente también funciona:

gsed -n -e 'H;${x;s/\\n/\n/g;p;}'
Dirk Hoffmann
fuente
-2

Necesita una solución en sed, y eso ya se proporciona a continuación. Pero quería agregar otra posibilidad de que, en mi humilde opinión, es más fácil y rápido,

tr -d "\n"
jpmuc
fuente
1
que hace esto eliminar todas las nuevas líneas de entrada?
mikeserv
Sí, eso es exactamente lo que hace
jpmuc
55
¿pero por qué? ¿Qué tiene que ver eso con la pregunta?
mikeserv
1
Esto simplemente elimina "\ n" cuando la pregunta es cómo reemplazar la cadena "\ n" con nuevas líneas reales.
Spuder