Me parece que \nno funciona en sed bajo Mac OS X. Específicamente, digamos que quiero dividir las palabras separadas por un solo espacio en líneas:
# input
foo bar
Yo suelo,
echo "foo bar" | sed 's/ /\n/'
Pero el resultado es estúpido, ¡ \nno se escapa!
foonbar
Después de consultar a google, encontré una solución alternativa :
echo 'foo bar' | sed -e 's/ /\'$'\n/g'
Después de leer el artículo, todavía no puedo entender lo que \'$'\n/g'significa. ¿Alguien me lo puede explicar o si hay alguna otra forma de hacerlo? ¡Gracias!

echo "foo bar" | tr ' ' '\n'\n.Respuestas:
Puede
brew install gnu-sedy reemplazar llamadassedcongsed.Si no desea anteponer la "g" a
sed, puedebrew install gnu-sed --with-default-namesy simplemente llamesed.(Editar: bandera de cerveza actualizada, punta de sombrero a Clément)
fuente
--with-default-namesy no--default-names. Sin embargo, esta opción no funcionó en mi instalación, por lo que tuve que poner unaalias gsed=seden mi~/.profilepara que funcione.seden OS X se comporta de la manera en que lo hace y hace una suposición incorrecta quegnu-sedes más correcta. No sea un adicto a GNU y cumpla con los estándares POSIX para evitar problemas a largo plazo.Estos también funcionarían:
echo 'foo bar' | sed $'s/ /\\\n/g'lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"El sed de OS X no se interpreta
\nen el patrón de reemplazo, pero puede usar un salto de línea literal precedido por un carácter de continuación de línea. El shell reemplaza$'\n'con un salto de línea literal antes de ejecutar el comando sed.fuente
sed $'s/ /\\\n/g'funciona, pero nosed $'s/\\\n/ /g'?sedincluso en linux / unix para eliminar nuevas líneas porque se analiza / divide en cada nueva línea. Si ejecuta esto en Linux / Unix, tampoco hará nada:echo -e 'foo\nbar' | sed 's/\n//'La solución alternativa que encontró pasa una cadena de argumento único a
sed -e.Ese argumento termina siendo una cadena en el
s/ / /gformato familiar sed .Esa cadena se crea en dos partes, una después de la otra.
La primera parte se cita en
'...'forma.La segunda parte se cita en
$'...'forma.La
's/ /\'parte elimina las comillas simples, pero de lo contrario pasa a sed tal como se ve en la línea de comandos. Es decir, la barra invertida no se come con bash, se pasa a sed.La
$'\n/g'parte obtiene el signo de dólar y las comillas simples quitadas, y el\nse convierte en un carácter de nueva línea.Todos juntos, el argumento se convierte
s / / \ newline/ g
[Eso fue divertido. Tomó un tiempo desenvolver eso. +1 para una pregunta interesante.]
fuente
La expresión
$'...'es unbash-ismo que produce...con las secuencias de escape estándar expandidas. Th\'antes sólo significa una barra invertida seguida por el extremo de la sección citada, la cadena resultante ess/ /\. (Sí, puede cambiar las comillas en el medio de una cadena; no termina la cadena).El estándar POSIX
sedsolo acepta\ncomo parte de un patrón de búsqueda. OS X usa FreeBSDsed, que es estrictamente compatible con POSIX; GNU, como de costumbre, agrega cosas adicionales y luego los usuarios de Linux piensan que es algún tipo de "estándar" (tal vez estaría más impresionado si alguno de ellos tuviera un proceso de estándares).fuente
$'...'parte. Pero ... que ess/ /\? ¿Qué quieres decir conswitch quoting?'...'es un tipo de citación de shell;$'...'es otro. También hay"..."y\xpara citar un solo personaje. Puede combinarlos en una sola palabra, que es lo que se estaba haciendo allí, cambiando de una''cadena normal a una$''cadena para traducir el\n. En cuanto al resto, está construyendo unsedcomando (s/text/replacement/flags). En este caso, se inicia el comando, que incluye una barra diagonal inversa al final para proteger la nueva línea literal que se$'\n/g'agrega. El resultado es reemplazar todos los/gespacios (la bandera) con nuevas líneas.Hay una manera muy fácil de ver visualmente lo que está sucediendo. ¡Simplemente repita la secuencia!
resultados en
que es equivalente a
s/$/\newline/gSi no tenía el extra
\antes delnewline, el shell interpretaríanewlineel final prematuramente del comando.fuente