Comment puis-je avoir un retour à la ligne dans une chaîne de caractères en sh?
Ce
STR="Hello\nWorld"
echo $STR
produit en sortie
Hello\nWorld
au lieu de
Hello
World
Que dois-je faire pour avoir un saut de ligne dans une chaîne de caractères?
Remarque: Cette question n'est pas sur echo.
Je suis conscient de echo -e
, mais je suis à la recherche d'une solution qui permet de passer d'une chaîne (qui comprend un retour à la ligne) comme un argument de autres commandes qui n'ont pas une option similaire à interpréter \n
's comme des retours à la ligne.
Vous devez vous connecter pour publier un commentaire.
La solution est d'utiliser
$'string'
, par exemple:Voici un extrait de la page de manuel de Bash:
IFS='^J'
et l'utiliser. Toute autre option connue?STR=$"Hello\nWorld"
imprime simplementHello\nWorld
.H="Hello"; W="World"; STR="${H}"$'\n'"${W}"; echo "${STR}"
echo "Bonjour" et "Monde" sur des lignes séparéesEcho est donc des années nonante et si pleine de périls que son utilisation devrait entraîner core dumps pas moins de 4 GO. Sérieusement, echo des problèmes ont été la raison pour laquelle les Unix processus de Normalisation enfin inventé le
printf
utilitaire, de faire disparaître tous les problèmes.Donc, pour obtenir un retour à la ligne dans une chaîne de caractères:
Là! Pas de SYSV vs BSD echo de la folie, tout est parfaitement imprimé et entièrement portable, soutien pour les séquences d'échappement. Tout le monde veuillez utiliser
printf
maintenant et ne jamais regarder en arrière.$'string'
est encore plus propre.$'foo'
syntaxe n'est pas valide POSIX syntaxe que de 2013. De nombreuses coquilles va se plaindre.BAR=$(printf "hello\nworld\n")
n'a pas l'impression de fin du \n pour moiecho "$BAR" something
et avoir "quelque chose" apparaître sur une nouvelle ligne.FOO
(supprimerworld
pour ne laisser que"
sur cette ligne.)$()
est spécifiée par POSIX suppression de séquences d'une ou de plusieurs <newline> caractères à la fin de la substitution.printf -v var "%s\n\n" "valuea" "valueb"
. Il semble conserver les deux dernières\n
. Indice:echo -n "$var"|xxd
. 🙂var="$(printf "%s\n\n" "vala" "valb" "x")";echo -n "${var%x}" |xxd'
less "$(printf '+&^ INFO\nF')" /var/log/some*.log
-v
drapeau deprintf
! Vu ici: unix.stackexchange.com/a/20039/39643Ce que j'ai fait sur la base des autres réponses a été
Le problème n'est pas avec le shell. Le problème est en fait avec la
echo
commande elle-même, et l'absence de guillemets autour de la variable d'interpolation. Vous pouvez essayer d'utiliserecho -e
mais qui n'est pas pris en charge sur toutes les plateformes, et l'une des raisonsprintf
est maintenant recommandé pour la portabilité.Vous pouvez également essayer et insérer la nouvelle ligne directement dans votre script shell (si un script est ce que vous avez écrit), de sorte qu'il ressemble...
ou, de manière équivalente
La seule alternative simple est de taper une nouvelle ligne dans la variable:
Oui, cela signifie que l'écriture Entrée en cas de besoin dans le code.
Il y a plusieurs équivalents à un
new line
caractère.Mais tous ceux qui nécessitent "une interprétation" par certains outil (POSIX printf):
Et, par conséquent, l'outil est nécessaire pour construire une chaîne de caractères avec une nouvelle ligne:
Dans quelques coquilles, la séquence $' est une coque spéciale expansion.
Connu pour travailler dans ksh93, bash et zsh:
Bien sûr, des solutions plus complexes sont également possibles:
Ou
- Je trouver les
-e
drapeau de l'élégant et simpleSi la chaîne est la sortie d'une autre commande, je viens d'utiliser les guillemets
echo
.echo -e
est tristement célèbre pour ses problèmes de portabilité. C'est moins d'un Sauvage de l'Ouest de la situation maintenant que la pré-POSIX, mais il n'y a toujours pas de raison de préférerecho -e
. Voir aussi stackoverflow.com/questions/11530203/...Un $ juste avant les guillemets simples '...\n... " comme suit, cependant guillemets doubles ne fonctionne pas.
Je ne suis pas un bash expert, mais celui-ci a fonctionné pour moi:
J'ai trouvé cela plus facile pour la mise en forme des textes.
Sur mon système (Ubuntu 17.10) ton exemple fonctionne comme souhaité, à la fois lorsqu'il est saisi à partir de la ligne de commande (dans
sh
) et lorsqu'il est exécuté comme unsh
script:Je suppose que cela répond à votre question: il fonctionne, tout simplement. (Je n'ai pas essayé de comprendre les détails tels que à quel moment exactement la substitution du caractère de saut de ligne pour
\n
qui se passe danssh
).Cependant, j'ai remarqué que ce même script ne se comportent différemment lorsqu'il est exécuté avec
bash
et affichera leHello\nWorld
à la place:J'ai réussi à obtenir le résultat souhaité avec
bash
comme suit:Notez les guillemets autour de
$STR
. Celle-ci se comporte de manière identique si enregistré et exécuté en tant quebash
script.Le suivant donne également la sortie désirée:
Ceux difficiles à l'égard de ceux qui ont juste besoin de le saut de ligne et de mépriser le multiligne code qui casse l'indentation, pourrait faire:
Bash (et, probablement, d'autres coquillages) avaler tous la fuite des retours à la ligne après la substitution de commande, de sorte que vous devez mettre fin à l'
printf
chaîne avec un non-caractère de saut de ligne et le supprimer par la suite. Cela peut aussi facilement devenir un oneliner.Je n'étais pas vraiment heureux avec toutes les options ici. C'est ce qui a fonctionné pour moi.
str=$(printf '%s\n' "first line" "another line" "and another line")
(le shell idéalement (ou pas) de garniture finale des retours à la ligne à partir de la commande de substitution). Plusieurs réponses ici déjà promouvoirprintf
sous diverses formes, donc je ne suis pas sûr que cela ajoute aucune valeur à une réponse distincte.printf '%s\n' "first line" \
(saut de ligne, tiret)'second line'
etc. Voir aussiprintf -v str
pour l'affectation à une variable sans frai un shell interne est exécuté.