La solution consiste à utiliser $'string'
, par exemple:
$ STR=$'Hello\nWorld'
$ echo "$STR" # quotes are required here!
Hello
World
Voici un extrait de la page de manuel 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.
STR=$"Hello\nWorld"
imprime simplementHello\nWorld
.H="Hello"; W="World"; STR="${H}"$'\n'"${W}"; echo "${STR}"
fera écho à "Hello" et "World" sur des lignes distinctesEcho a tellement quatre-vingt-dix et est si lourd de dangers que son utilisation devrait entraîner des vidages de mémoire d'au moins 4 Go. Sérieusement, les problèmes d'écho étaient la raison pour laquelle le processus de normalisation Unix a finalement inventé l'
printf
utilitaire, supprimant tous les problèmes.Donc, pour obtenir une nouvelle ligne dans une chaîne:
Là! Pas de folie d'écho SYSV vs BSD, tout est parfaitement imprimé et entièrement portable pour les séquences d'échappement C. Tout le monde, veuillez utiliser
printf
maintenant et ne jamais regarder en arrière.la source
$'string'
est encore plus propre.$'foo'
syntaxe n'est pas une syntaxe POSIX valide à partir de 2013. De nombreux shells se plaindront.BAR=$(printf "hello\nworld\n")
n'imprime pas le trailing \ n pour moi$()
est spécifié par POSIX comme supprimant les séquences d'un ou plusieurs caractères <newline> à la fin de la substitution .Ce que j'ai fait sur la base des autres réponses était
la source
Le problème n'est pas avec le shell. Le problème est en fait avec la
echo
commande elle-même, et le manque de guillemets autour de l'interpolation variable. Vous pouvez essayer d'utiliserecho -e
mais cela n'est pas pris en charge sur toutes les plates-formes, et l'une des raisonsprintf
est maintenant recommandée pour la portabilité.Vous pouvez également essayer d'insérer la nouvelle ligne directement dans votre script shell (si un script est ce que vous écrivez) pour qu'il ressemble à ...
ou équivalent
la source
Je trouve le
-e
drapeau élégant et simpleSi la chaîne est la sortie d'une autre commande, j'utilise simplement des guillemets
la source
echo
.echo -e
est connu pour ses problèmes de portabilité. Il s'agit moins d'une situation dans le Far West que pré-POSIX, mais il n'y a toujours aucune raison de préférerecho -e
. Voir aussi stackoverflow.com/questions/11530203/…La seule alternative simple est de taper réellement une nouvelle ligne dans la variable:
Oui, cela signifie écrire Enterlà où c'est nécessaire dans le code.
Il existe plusieurs équivalents à un
new line
personnage.Mais tous ceux-ci nécessitent "une interprétation" par un outil ( POSIX printf ):
Et par conséquent, l'outil est nécessaire pour créer une chaîne avec une nouvelle ligne:
Dans certains shells, la séquence $'est une extension de shell spéciale. Connu pour fonctionner dans ksh93, bash et zsh:
Bien entendu, des solutions plus complexes sont également possibles:
Ou
la source
Un $ juste avant les guillemets simples '... \ n ...' comme suit, mais les guillemets doubles ne fonctionnent pas.
la source
Je ne suis pas un expert bash, mais celui-ci a fonctionné pour moi:
J'ai trouvé cela plus facile à mettre en forme les textes.
la source
$NEWSTR
deecho "$NEWSTR"
sont importants iciSur mon système (Ubuntu 17.10), votre exemple fonctionne comme vous le souhaitez, à la fois lorsqu'il est saisi à partir de la ligne de commande (dans
sh
) et lorsqu'il est exécuté en tant quesh
script:Je suppose que cela répond à votre question: cela fonctionne. (Je n'ai pas essayé de comprendre des détails comme à quel moment exactement la substitution du caractère de nouvelle ligne
\n
se produitsh
).Cependant, j'ai remarqué que ce même script se comporterait différemment lorsqu'il serait exécuté avec
bash
et s'imprimerait à laHello\nWorld
place:J'ai réussi à obtenir la sortie souhaitée avec
bash
comme suit:Notez les guillemets autour
$STR
. Cela se comporte de manière identique s'il est enregistré et exécuté en tant quebash
script.Ce qui suit donne également la sortie souhaitée:
la source
Ceux difficiles qui ont juste besoin de la nouvelle ligne et méprisent le code multiligne qui rompt l'indentation, pourraient faire:
Bash (et probablement d'autres shells) engloutit tous les sauts de ligne après la substitution de commande, vous devez donc terminer la
printf
chaîne avec un caractère non nouveau et le supprimer ensuite. Cela peut également facilement devenir un oneliner.la source
Je n'étais pas vraiment satisfait de l'une des options ici. C'est ce qui a fonctionné pour moi.
la source
str=$(printf '%s\n' "first line" "another line" "and another line")
(le shell coupera commodément (ou non) toutes les nouvelles lignes finales de la substitution de commande). Plusieurs réponses ici promeuvent déjàprintf
sous diverses formes, donc je ne suis pas sûr que cela ajoute une valeur en tant que réponse distincte.printf '%s\n' "first line" \
(saut de ligne, retrait),'second line'
etc. Voir aussiprintf -v str
pour l'affectation à une variable sans engendrer un sous-shell.