saltos salto original nueva linea data content sh

salto - ¿Cómo puedo tener una nueva línea en una cadena en sh?



saltos de linea en jquery (10)

Esta

STR="Hello/nWorld" echo $STR

produce como salida

Hello/nWorld

en lugar de

Hello World

¿Qué debo hacer para tener una nueva línea en una cadena?

Nota: Esta pregunta no es sobre eco . Soy consciente de echo -e , pero estoy buscando una solución que permita pasar una cadena (que incluye una nueva línea) como argumento a otros comandos que no tienen una opción similar para interpretar las /n ''s como nuevas líneas.


  1. La única alternativa simple es escribir una nueva línea en la variable:

    $ STR=''new line'' $ printf ''%s'' "$STR" new line

    Sí, eso significa escribir Ingrese donde sea necesario en el código.

  2. Hay varios equivalentes a una new line caracteres.

    /n ### A common way to represent a new line character. /012 ### Octal value of a new line character. /x0A ### Hexadecimal value of a new line character.

    Pero todos aquellos requieren "una interpretación" por alguna herramienta ( POSIX printf ):

    echo -e "new/nline" ### on POSIX echo, `-e` is not required. printf ''new/nline'' ### Understood by POSIX printf. printf ''new/012line'' ### Valid in POSIX printf. printf ''new/x0Aline'' printf ''%b'' ''new/0012line'' ### Valid in POSIX printf.

    Y por lo tanto, se requiere la herramienta para construir una cadena con una nueva línea:

    $ STR="$(printf ''new/nline'')" $ printf ''%s'' "$STR" new line

  3. En algunas conchas, la secuencia $ '' es una expansión de concha especial. Conocido para trabajar en ksh93, bash y zsh:

    $ STR=$''new/nline''

  4. Por supuesto, también son posibles soluciones más complejas:

    $ echo ''6e65770a6c696e650a'' | xxd -p -r new line

    O

    $ echo "new line" | sed ''s/ /+//n/g'' new line


A $ justo antes de las comillas simples ''... / n ...'' de la siguiente manera, sin embargo, las comillas dobles no funcionan.

$ echo $''Hello/nWorld'' Hello World $ echo $"Hello/nWorld" Hello/nWorld


Aquellos exigentes que necesitan solo la nueva línea y desprecian el código multilínea que rompe la sangría, podrían hacer:

IFS="$(printf ''/nx'')" IFS="${IFS%x}"

Bash (y probablemente otros shells) se traga todas las nuevas líneas finales después de la sustitución del comando, por lo que debe terminar la cadena printf con un carácter que no sea newline y luego borrarlo. Esto también puede convertirse fácilmente en un oneliner.

IFS="$(printf ''/nx'')" IFS="${IFS%x}"

Sé que esto es dos acciones en lugar de una, pero mi sangrado y portabilidad OCD está en paz ahora :) Originalmente desarrollé esto para poder dividir la salida separada solo de nueva línea y terminé usando una modificación que usa /r como la terminación personaje. Eso hace que la división de nueva línea funcione incluso para la salida de dos que termina con /r/n .

IFS="$(printf ''/n/r'')"


El eco es tan noventa y tan lleno de peligros que su uso debería resultar en volcados de núcleo no menos de 4 GB. En serio, los problemas de eco fueron la razón por la cual el proceso de Estandarización de Unix finalmente inventó la utilidad printf , eliminando todos los problemas.

Así que para obtener una nueva línea en una cadena:

FOO="hello world" BAR=$(printf "hello/nworld/n") # Alternative; note: final newline is deleted printf ''<%s>/n'' "$FOO" printf ''<%s>/n'' "$BAR"

¡Ahí! Sin la locura por el eco de SYSV y BSD, todo se imprime perfectamente y es totalmente compatible con las secuencias de escape C. Todos, por favor, usen printf ahora y nunca miren atrás.


El problema no es con la concha. El problema es en realidad con el comando echo sí, y la falta de comillas dobles alrededor de la variable interpolación. Puede intentar usar echo -e pero eso no es compatible con todas las plataformas, y una de las razones por las que se recomienda printf es la portabilidad.

También puedes probar e insertar la nueva línea directamente en tu script de shell (si un script es lo que estás escribiendo) para que se vea como ...

#!/bin/sh echo "Hello World" #EOF

o equivalente

#!/bin/sh string="Hello World" echo "$string" # note double quotes!


En mi sistema (Ubuntu 17.10), su ejemplo funciona como se desea, tanto cuando se escribe desde la línea de comandos (en sh ) como cuando se ejecuta como un script sh :

[bash]§ sh $ STR="Hello/nWorld" $ echo $STR Hello World $ exit [bash]§ echo "STR=/"Hello/nWorld/" > echo /$STR" > test-str.sh [bash]§ cat test-str.sh STR="Hello/nWorld" echo $STR [bash]§ sh test-str.sh Hello World

Supongo que esto responde a tu pregunta: simplemente funciona. (No he intentado averiguar detalles como en qué momento exactamente la sustitución del carácter de nueva línea por /n ocurre en sh ).

Sin embargo, me di cuenta de que este mismo script se comportaría de manera diferente cuando se ejecutara con bash y que en su lugar imprimiría Hello/nWorld :

[bash]§ bash test-str.sh Hello/nWorld

He logrado obtener la salida deseada con bash siguiente manera:

[bash]§ STR="Hello > World" [bash]§ echo "$STR"

Tenga en cuenta las comillas dobles alrededor de $STR . Esto se comporta de manera idéntica si se guarda y se ejecuta como un script bash .

Lo siguiente también da el resultado deseado:

[bash]§ echo "Hello > World"


La solución es usar $''string'' , por ejemplo:

$ STR=$''Hello/nWorld'' $ echo "$STR" Hello World

Aquí hay un extracto de la página del manual de Bash:

Words of the form $''string'' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows: /a alert (bell) /b backspace /e /E an escape character /f form feed /n new line /r carriage return /t horizontal tab /v vertical tab // backslash /' single quote /" double quote /nnn the eight-bit character whose value is the octal value nnn (one to three digits) /xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) /cx a control-x character The expanded result is single-quoted, as if the dollar sign had not been present. A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.


Lo que hice en base a las otras respuestas fue

NEWLINE=$''/n'' my_var="__between eggs and bacon__" echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight" # which outputs: spam eggs__between eggs and bacon__bacon knight


Me parece que la bandera es elegante y directa.

STR="Hello/nWorld" echo -e $STR #outputs Hello World

Si la cadena es la salida de otro comando, solo uso comillas

indexes_diff=$(git diff index.yaml) echo "$indexes_diff"


No soy un experto en bash, pero este me funcionó:

STR1="Hello" STR2="World" NEWSTR=$(cat << EOF $STR1 $STR2 EOF ) echo "$NEWSTR"

Me pareció más fácil formatear los textos.