Quelle est la syntaxe str=$'Hello World\n===========\n'appelée? substitution variable?
Zengr
5
@zengr: Cela s'appelle ANSI-C , mais il est aussi supporté dans zshet ksh; Cependant, il n'est pas compatible POSIX.
mklement0
4
@ mkelement0, il provient de ksh93, est également soutenu par zsh, bash, mksh et FreeBSD sh, et son inclusion dans la prochaine révision majeure de POSIX est en cours de discussion
Stéphane Chazelas le
1
Ne semble pas fonctionner avec des guillemets doubles? par exemple str=$"My $PET eats:\n$PET food"? Cette approche fonctionne pour les guillemets doubles
Brad Parks
31
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'HelloWorld===========
EOF
Si vous souhaitez stocker la chaîne dans une variable, utilisez la catcommande 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'HelloWorld===========
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.
J'utilise GNU bash 4.1.5 et 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.
Peter.O
@fred Bons points, j'ai déjà expliqué les nouvelles lignes de fin et le code indiqué qui fonctionne sous bash. Je pense que c'est un bug dans bash, bien que pour être honnête après avoir relu la spécification POSIX, je ne vois pas clairement que le comportement est obligatoire lorsque le << se trouve à l'intérieur d'une substitution de commande et que l'heredoc ne l'est pas.
Gilles 'SO- arrête d'être méchant'
Super trucs; pour conserver les \ninstances de fin (et principales) bashlors 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).
BTW. \ N n'est pas nécessaire, car vous echoen 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).
Peter.O
+1 De toutes les solutions, celle-ci est la plus directe et la plus simple.
Hai Vu le
echo -e ne fonctionne pas sous OS X
Greg M. Krsak
2
@GregKrsak: En bash, echo -efait le travail sur OS X - c'est parce que echoest 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 -etravaille kshet zshaussi). En revanche, l’ utilitaire externeecho sous OS X - /bin/echo- n’est en effet pas pris en charge -e.
mklement0
4
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}"
Pourrais-je demander une explication aux votants descendants?
pihentagy
Agréable! Cela peut être inclus dans les variables à l'aide de guillemets doubles, par exemple"My dog eats:${NL}dog food"
Brad Parks
Cela a fonctionné pour moi. Lors de l'utilisation d'un script bash pour composer une chaîne qui est automatiquement copiée dans le Presse-papiers pour un collage ultérieur, cette approche a fonctionné pour l'ajout de nouvelles lignes dans la sortie résultante.
Ville
3
De toute discussion, voici le moyen le plus simple pour moi:
bash$ str="Hello World
==========="
bash$ echo "$str"HelloWorld===========
La commande echo doit utiliser des guillemets doubles .
Si vous utilisez bashet préférez utiliser de nouvelles lignes réelles pour des raisons de lisibilité , readune 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 \nHelloWorld===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"[HelloWorld===========]
-rgarantit que readn'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 readqui 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 readcommande 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.HelloWorld===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.# Note how the leading tabs were stripped.
$ echo "$str"[HelloWorld===========]
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.
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:
[[HelloWorld===========]]
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.
Réponses:
En
bash
vous pouvez utiliser la syntaxeLes 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 variableLes 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:
parce que lorsque vous imprimez la chaîne sans guillemets, les nouvelles lignes sont converties en espaces.
la source
str=$'Hello World\n===========\n'
appelée? substitution variable?zsh
etksh
; Cependant, il n'est pas compatible POSIX.str=$"My $PET eats:\n$PET food"
? Cette approche fonctionne pour les guillemets doublesVous pouvez mettre les retours à la ligne littéraux entre guillemets simples (dans n’importe quel shell Bourne / style POSIX).
Pour une chaîne multiligne, les documents sont souvent pratiques. La chaîne est introduite en entrée d'une commande.
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 écrirestr=$(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.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.la source
str=$(cat <<'EOF')
ne fonctionne pas tel quel. Il)
doit être placé sur la ligne suivante après la fin du documentEOF
.. 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érezIFS= read -r -d '' str <<'EOF'...
comme une alternative à l'approche par le bouchon (voir ma réponse).Utilisez-vous "echo"? Essayez "echo -e".
la source
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 queecho
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
travailleksh
etzsh
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).
la source
$''
besoin d'un sous-shell?"My dog eats:${NL}dog food"
De toute discussion, voici le moyen le plus simple pour moi:
La commande echo doit utiliser des guillemets doubles .
la source
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.-r
garantit queread
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, ceread
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 simplementread -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 à laread
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é:
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.la source
vous devez le faire de cette façon:
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:
testons-le:
nous donne maintenant:
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
.la source
sortie:
la source
result+=$foo$'\n'
?$(printf %s "$foo")
découperait les derniers caractères de nouvelle ligne dans le$foo
cas échéant.