¿Cómo se str=$'Hello World\n===========\n'llama la sintaxis ? sustitución variable?
zengr
55
@zengr: Se llama cita ANSI-C , y también es compatible con zshy ksh; sin embargo, NO es compatible con POSIX.
mklement0
44
@ mkelement0, proviene de ksh93, también es compatible con zsh, bash, mksh y FreeBSD sh, y su inclusión en la próxima revisión importante de POSIX está en discusión
Stéphane Chazelas
1
¿No parece funcionar con comillas dobles? por ejemplo str=$"My $PET eats:\n$PET food"? Este enfoque funciona para comillas dobles
Brad Parks
31
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'HelloWorld===========
EOF
Si desea almacenar la cadena en una variable, use el catcomando 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'HelloWorld===========
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.
Estoy usando GNU bash 4.1.5, y 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.
Peter.O
@fred Buenos puntos, he explicado sobre las nuevas líneas finales y el código mostrado que funciona en bash. Creo que es un error en bash, aunque para ser honesto al volver a leer la especificación POSIX, no está claro que el comportamiento sea obligatorio cuando el << está dentro de una sustitución de comando y el heredoc no.
Gilles 'SO- deja de ser malvado'
Buena cosa; para preservar las \ninstancias finales (y iniciales) bashal 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).
Por cierto. No necesita la \ n final, porque echoagregará 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).
Peter.O
+1 De todas las soluciones, esta es la más directa y simple.
Hai Vu
echo -e no funciona en OS X
Greg M. Krsak
2
@GregKrsak: En bash, echo -ehace el trabajo en OS X - eso es porque echoes 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 -efunciona en kshy zshtambién). Por el contrario, sin embargo, la utilidad externaecho en OS X /bin/echo- de hecho no es compatible -e.
mklement0
4
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}"
¿Podría pedir una explicación a los votantes negativos?
pihentagy
¡Agradable! Esto se puede incluir en variables usando comillas dobles, por ejemplo"My dog eats:${NL}dog food"
Brad Parks,
Esto funcionó para mí. Cuando se usa un script bash para componer una cadena que se copia automáticamente en el portapapeles para su posterior pegado en otro lugar, este enfoque funcionó para agregar nuevas líneas en la salida resultante.
Ville
3
De todas las discusiones, esta es la forma más simple para mí:
bash$ str="Hello World
==========="
bash$ echo "$str"HelloWorld===========
Para complementar las excelentes respuestas existentes:
Si está usando bashy prefiere usar nuevas líneas reales para facilitar la lectura , reades 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 \nHelloWorld===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"[HelloWorld===========]
-rgarantiza que readno 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 readque 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 readcomando 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.HelloWorld===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.# Note how the leading tabs were stripped.
$ echo "$str"[HelloWorld===========]
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.
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:
[[HelloWorld===========]]
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.
Respuestas:
En
bash
puedes usar la sintaxisLas 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 variableAmbas soluciones no requieren una subshell.
Si en lo siguiente necesita imprimir la cadena, debe usar comillas dobles, como en el siguiente ejemplo:
porque cuando imprime la cadena sin comillas, la nueva línea se convierte en espacios.
fuente
str=$'Hello World\n===========\n'
llama la sintaxis ? sustitución variable?zsh
yksh
; sin embargo, NO es compatible con POSIX.str=$"My $PET eats:\n$PET food"
? Este enfoque funciona para comillas doblesPuede poner nuevas líneas literales entre comillas simples (en cualquier shell de estilo Bourne / POSIX).
Para una cadena multilínea, aquí los documentos son a menudo convenientes. La cadena se alimenta como entrada a un comando.
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 escribirstr=$(cat <<'EOF'); str=${str%a}
seguido del heredoc propiamente dicho, pero bash requiere que el heredoc aparezca antes del paréntesis de cierre.En ksh, bash y zsh, puede usar el
$'…'
formulario entre comillas para expandir los escapes de barra invertida dentro de las comillas.fuente
str=$(cat <<'EOF')
no funciona tal como está ...)
Debe colocarse en la siguiente línea después del final del documentoEOF
... 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, considereIFS= read -r -d '' str <<'EOF'...
como una alternativa al enfoque de detención (vea mi respuesta).¿Estás usando "echo"? Prueba "echo -e".
fuente
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 porqueecho
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 enksh
yzsh
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).
fuente
$''
requeriría una subshell?"My dog eats:${NL}dog food"
De todas las discusiones, esta es la forma más simple para mí:
El comando echo debe usar comillas dobles .
fuente
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.-r
garantiza queread
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, loread
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 soloread -r -d ''
, pero tenga en cuenta que cualquier espacio en blanco inicial y final se conserva.(Tenga en cuenta que anteponer
IFS=
directamente alread
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:
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.fuente
necesitas hacerlo de esta manera:
Actualizar:
Como Fred lo señaló, de esta manera perderá "\ n" al final. Para asignar variables con secuencias de barra invertida expandidas, haga:
probémoslo:
nos da ahora:
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
.fuente
salida:
fuente
result+=$foo$'\n'
?$(printf %s "$foo")
recortaría los caracteres de la nueva línea final en$foo
caso de haberlos.