Quand je fais
str="Hello World\n===========\n"
Je reçois aussi les \n
imprimés. Comment puis-je avoir de nouvelles lignes alors?
Quand je fais
str="Hello World\n===========\n"
Je reçois aussi les \n
imprimés. Comment puis-je avoir de nouvelles lignes alors?
Réponses:
En bash
vous pouvez utiliser la syntaxe
str=$'Hello World\n===========\n'
Les guillemets simples précédés de $
est une nouvelle syntaxe permettant d'insérer des séquences d'échappement dans des chaînes.
Également printf
intégré, permet d’enregistrer le résultat obtenu dans une variable
printf -v str 'Hello World\n===========\n'
Les deux solutions ne nécessitent pas de sous-shell.
Si, dans ce qui suit, vous devez imprimer la chaîne, vous devez utiliser des guillemets, comme dans l'exemple suivant:
echo "$str"
parce que lorsque vous imprimez la chaîne sans guillemets, les nouvelles lignes sont converties en espaces.
str=$'Hello World\n===========\n'
appelée? substitution variable?
str=$"My $PET eats:\n$PET food"
? Cette approche fonctionne pour les guillemets doubles
Vous pouvez mettre les retours à la ligne littéraux entre guillemets simples (dans n’importe quel shell Bourne / style POSIX).
str='Hello World
===========
'
Pour une chaîne multiligne, les documents sont souvent pratiques. La chaîne est introduite en entrée d'une commande.
mycommand <<'EOF'
Hello World
===========
EOF
Si vous souhaitez stocker la chaîne dans une variable, utilisez la cat
commande dans une substitution de commande. Le ou les caractères de nouvelle ligne à la fin de la chaîne seront supprimés par la substitution de commande. Si vous souhaitez conserver les nouvelles lignes définitives, placez un bouchon à la fin et éliminez-le ensuite. Dans les shells compatibles POSIX, vous pouvez écrire str=$(cat <<'EOF'); str=${str%a}
suivi de l'hérédoc proprement dit, mais bash exige que l'hérédoc apparaisse avant la parenthèse fermante.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
Dans ksh, bash et zsh, vous pouvez utiliser le $'…'
formulaire cité pour développer des échappements de barre oblique inversée à l'intérieur des guillemets.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
ne fonctionne pas tel quel. Il )
doit être placé sur la ligne suivante après la fin du document EOF
.. mais malgré cela, il perd le retour à la ligne suivant en raison de la commande Substitution.
\n
instances de fin (et principales) bash
lors de la capture d'un here-doc dans une variable, considérez IFS= read -r -d '' str <<'EOF'...
comme une alternative à l'approche par le bouchon (voir ma réponse).
Utilisez-vous "echo"? Essayez "echo -e".
echo -e "Hello World\n===========\n"
echo
en ajouterez automatiquement un, sauf si vous spécifiez -n. (Cependant, le principal problème de la question est de savoir comment obtenir ces nouvelles lignes dans une variable).
bash
, echo -e
fait le travail sur OS X - c'est parce que echo
est une fête builtin (plutôt que d' un exécutable externe) et que le soutien ne builtin -e
. (En builtin, il devrait fonctionner sur toutes les plates - formes qui bash fonctionne sur, soit dit en passant, echo -e
travaille ksh
et zsh
aussi). En revanche, l’ utilitaire externeecho
sous OS X - /bin/echo
- n’est en effet pas pris en charge -e
.
Si vous avez souvent besoin de nouvelles lignes dans votre script, vous pouvez déclarer une variable globale contenant une nouvelle ligne. De cette façon, vous pouvez l'utiliser dans des chaînes entre guillemets (extensions de variable).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
besoin d'un sous-shell?
"My dog eats:${NL}dog food"
Pour compléter les grandes réponses existantes:
Si vous utilisez bash
et préférez utiliser de nouvelles lignes réelles pour des raisons de lisibilité , read
une autre option est de capturer un document here dans une variable , qui (comme les autres solutions ici) ne nécessite pas l'utilisation d'un sous-shell.
# 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
garantit que read
n'interprète pas l'entrée (par défaut, les barres obliques inverses sont traitées comme telles, mais cela est rarement nécessaire).
-d ''
définit le délimiteur "record" sur une chaîne vide, ce read
qui entraîne la lecture complète de l' entrée en une seule fois (au lieu d'une seule ligne).
Notez qu'en laissant $IFS
(le séparateur de champ interne) sa valeur par défaut $' \t\n'
(un espace, un onglet, une nouvelle ligne), tous les espaces de début et de fin sont supprimés de la valeur affectée $str
, ce qui inclut le retour à la ligne arrière du doc-doc.
(Notez que même si le corps de l'ici-doc commence sur la ligne après le délimiteur de départ ( 'EOF'
ici), il ne pas contenir un premier saut de ligne).
Il s'agit généralement du comportement souhaité, mais si vous souhaitez utiliser ce retour à la ligne final, utilisez IFS= read -r -d ''
plutôt que simplement read -r -d ''
, mais notez que tous les espaces de début et de fin sont ensuite conservés.
(Notez que l'ajout IFS=
direct directement à la read
commande signifie que l'affectation est effective uniquement pendant cette commande. Il n'est donc pas nécessaire de restaurer la valeur précédente.)
L'utilisation d'un document ici vous permet également d' utiliser éventuellement l'indentation pour définir la chaîne multiligne aux fins de lisibilité:
# 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
===========]
Le placement -
entre <<
et le délimiteur here-doc d’ouverture ( 'EOF'
, ici) entraîne la suppression des caractères de tabulation principaux du corps de cet document et même du délimiteur de fermeture, mais notez que cela ne fonctionne qu'avec les caractères de tabulation réels , pas les espaces. l’éditeur traduit les tabulations en espaces, un travail supplémentaire est nécessaire.
vous devez le faire de cette façon:
STR=$(echo -ne "Hello World\n===========\n")
Mise à jour:
Comme Fred l'a souligné, vous perdrez ainsi le caractère "\ n". Pour affecter des variables avec des séquences de barres obliques inverses développées, procédez comme suit:
STR=$'Hello World\n===========\n\n'
testons-le:
echo "[[$STR]]"
nous donne maintenant:
[[Hello World
===========
]]
Notez que $ '' est différent de $ "". La seconde effectue la traduction en fonction de la localisation actuelle. Pour deital, voir la section QUOTING 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"
sortie:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
découperait les derniers caractères de nouvelle ligne dans le $foo
cas échéant.