Cuando lo hago
str="Hello World\n===========\n"
Me sale el \n
impreso también. ¿Cómo puedo tener nuevas líneas entonces?
Cuando lo hago
str="Hello World\n===========\n"
Me sale el \n
impreso también. ¿Cómo puedo tener nuevas líneas entonces?
Respuestas:
En bash
puedes usar la sintaxis
str=$'Hello World\n===========\n'
Las comillas simples precedidas por a $
son una nueva sintaxis que permite insertar secuencias de escape en cadenas.
También printf
incorporado permite guardar la salida resultante en una variable
printf -v str 'Hello World\n===========\n'
Ambas soluciones no requieren una subshell.
Si en lo siguiente necesita imprimir la cadena, debe usar comillas dobles, como en el siguiente ejemplo:
echo "$str"
porque cuando imprime la cadena sin comillas, la nueva línea se convierte en espacios.
str=$'Hello World\n===========\n'
llama la sintaxis ? sustitución variable?
zsh
y ksh
; sin embargo, NO es compatible con POSIX.
str=$"My $PET eats:\n$PET food"
? Este enfoque funciona para comillas dobles
Puede poner nuevas líneas literales entre comillas simples (en cualquier shell de estilo Bourne / POSIX).
str='Hello World
===========
'
Para una cadena multilínea, aquí los documentos son a menudo convenientes. La cadena se alimenta como entrada a un comando.
mycommand <<'EOF'
Hello World
===========
EOF
Si desea almacenar la cadena en una variable, use el cat
comando en una sustitución de comando. La sustitución del comando eliminará los caracteres de nueva línea al final de la cadena. Si desea retener las nuevas líneas finales, coloque un tapón al final y luego quítelo. En shells compatibles con POSIX, puede escribir str=$(cat <<'EOF'); str=${str%a}
seguido del heredoc propiamente dicho, pero bash requiere que el heredoc aparezca antes del paréntesis de cierre.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
En ksh, bash y zsh, puede usar el $'…'
formulario entre comillas para expandir los escapes de barra invertida dentro de las comillas.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
no funciona tal como está ... )
Debe colocarse en la siguiente línea después del final del documento EOF
... pero aun así, pierde la nueva línea final debido a Command Sustitución.
\n
instancias finales (y iniciales) bash
al capturar un documento aquí en una variable, considere IFS= read -r -d '' str <<'EOF'...
como una alternativa al enfoque de detención (vea mi respuesta).
¿Estás usando "echo"? Prueba "echo -e".
echo -e "Hello World\n===========\n"
echo
agregará automáticamente una, a menos que especifique -n. (Sin embargo, la mayor parte de la pregunta es cómo obtener estas nuevas líneas en una variable).
bash
, echo -e
hace el trabajo en OS X - eso es porque echo
es una fiesta de orden interna (en lugar de un ejecutable externo) y que hace de soporte incorporado -e
. (Como incorporado, debería funcionar en todas las plataformas en las que se ejecuta bash; por cierto, echo -e
funciona en ksh
y zsh
también). Por el contrario, sin embargo, la utilidad externaecho
en OS X /bin/echo
- de hecho no es compatible -e
.
Si necesita nuevas líneas en su script muchas veces, puede declarar una variable global que contenga una nueva línea. De esa manera, puede usarlo en cadenas entre comillas dobles (expansiones variables).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
requeriría una subshell?
"My dog eats:${NL}dog food"
Para complementar las excelentes respuestas existentes:
Si está usando bash
y prefiere usar nuevas líneas reales para facilitar la lectura , read
es otra opción para capturar un documento aquí en una variable que (como otras soluciones aquí) no requiere el uso de una subshell.
# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF' # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
-r
garantiza que read
no interprete la entrada (de forma predeterminada, trataría las barras invertidas especiales, pero eso rara vez se necesita).
-d ''
establece el delimitador de "registro" en una cadena vacía, lo read
que hace que lea toda la entrada de una vez (en lugar de solo una línea).
Tenga en cuenta que al dejar $IFS
(el separador de campo interno) en su valor predeterminado $' \t\n'
(un espacio, una pestaña, una nueva línea), cualquier espacio en blanco inicial y final se recorta del valor asignado a $str
, que incluye la nueva línea final de here-doc.
(Tenga en cuenta que a pesar de que el cuerpo de aquí-doc comienza en la línea después del delimitador de inicio ( 'EOF'
aquí), esto no contiene ningún líder de salto de línea).
Por lo general, este es el comportamiento deseado, pero si desea esa nueva línea final, use en IFS= read -r -d ''
lugar de solo read -r -d ''
, pero tenga en cuenta que cualquier espacio en blanco inicial y final se conserva.
(Tenga en cuenta que anteponer IFS=
directamente al read
comando significa que la asignación está vigente solo durante ese comando, por lo que no es necesario restaurar el valor anterior).
El uso de un documento aquí también le permite utilizar opcionalmente la sangría para activar la cadena de varias líneas para facilitar la lectura:
# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
Hello World
===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]
Colocar -
entre <<
y el delimitador here-doc de apertura ( 'EOF'
, aquí) hace que los caracteres de tabulación iniciales se eliminen del cuerpo de here-doc e incluso del delimitador de cierre, pero tenga en cuenta que esto solo funciona con caracteres de tabulación reales , no espacios, así que si su el editor traduce las pulsaciones de teclas en espacios, se necesita trabajo adicional.
necesitas hacerlo de esta manera:
STR=$(echo -ne "Hello World\n===========\n")
Actualizar:
Como Fred lo señaló, de esta manera perderá "\ n" al final. Para asignar variables con secuencias de barra invertida expandidas, haga:
STR=$'Hello World\n===========\n\n'
probémoslo:
echo "[[$STR]]"
nos da ahora:
[[Hello World
===========
]]
Tenga en cuenta que $ '' es diferente de $ "". El segundo hace la traducción de acuerdo con la configuración regional actual. Para deital vea la sección CITA en man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
salida:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
recortaría los caracteres de la nueva línea final en $foo
caso de haberlos.