Ici, le problème est que vous entourez la variable avec des guillemets doubles (""). Supprimez-le et tout ira bien.
VAR="This displays with \
extra spaces."
echo ${VAR}
Sortie
This displays with extra spaces.
Ici, le problème est que les doubles guillemets d'une variable préservent tous les caractères d'espaces. Ceci peut être utilisé dans le cas où vous en avez explicitement besoin.
Par exemple,
$ echo "Hello World ........ ... ...."
imprimera
Hello World ........ ... ....
Et en enlevant les guillemets, ses différents
$ echo Hello World ........ ... ....
Hello World ........ ... ....
Ici, le Bash supprime les espaces supplémentaires dans le texte car, dans le premier cas, le texte entier est considéré comme un argument "unique", préservant ainsi les espaces supplémentaires. Mais dans le second cas, la echo
commande reçoit le texte sous forme de 5 arguments.
Il est également utile de citer une variable lors de la transmission des arguments aux commandes.
Dans la commande ci-dessous, echo
n’obtient qu’un seul argument en tant que"Hello World"
$ variable="Hello World"
$ echo "$variable"
Mais dans le cas du scénario ci-dessous, on echo
obtient deux arguments au fur Hello
et à mesure queWorld
$ variable="Hello World"
$ echo $variable
$IFS
sont un outil puissant et universel - mais le code écrit de cette manière ne peut jamais produire de résultats fiables, de quelque type que ce soit.*
?
[]
).Les solutions proposées par esuoxu et Mickaël Bucas sont le moyen le plus courant et le plus portable de le faire.
Voici quelques
bash
solutions (dont certaines devraient également fonctionner dans d'autres coques, commezsh
). Tout d'abord avec l'+=
opérateur append (qui fonctionne de manière légèrement différente pour chacune d'une variable entière, d'une variable régulière et d'un tableau).Si vous voulez des nouvelles lignes (ou d'autres espaces / espaces) dans le texte, utilisez
$''
plutôt la citation:Ensuite, en utilisant
printf -v
pour assigner une valeur formatée à une variableL'astuce ici est qu'il y a plus d'arguments que de spécificateurs de format. Ainsi, contrairement à la plupart des
printf
fonctions, la personne bash réutilise la chaîne de formatage jusqu'à épuisement. Vous pouvez insérer une\n
chaîne dans le format ou utiliser $ '' (ou les deux) pour traiter les espaces.Ensuite, en utilisant un tableau:
Vous pouvez également utiliser
+=
pour construire le texte ligne par ligne (notez le()
):Ici cependant, vous devez vous rappeler d’aplatir le tableau si vous voulez tout le contenu du texte en une fois.
(Les tableaux indexés sur des entiers sont implicitement triés, contrairement aux tableaux associatifs). Cela vous donne un peu plus de souplesse, car vous pouvez manipuler des lignes et même des tranches et des dés si nécessaire.
Enfin, en utilisant
read
oureadarray
et un "here-document":La forme ici-document de
<<-
signifie que tous les onglets durs principaux sont supprimés de l'entrée, vous devez donc utiliser des onglets pour indenter votre texte. Les guillemets"EOT"
empêchent les fonctionnalités d'expansion du shell, donc l'entrée est utilisée telle quelle. Avecread
cela utilise une entrée délimitée par des octets NUL, de sorte qu'elle lise le texte délimité par une nouvelle ligne en une fois. Avecreadarray
(aliasmapfile
, disponible depuis bash-4.0), il lit dans un tableau et-t
supprime les nouvelles lignes sur chaque ligne.la source
read
option avechere document
est très sympa! Utile pour incorporer des scripts python et exécuter avecpython -c
. Je faisaisscript=$(cat <here document>)
avant, maisread -r -d '' script <here document>
c'est beaucoup mieux.Il existe une syntaxe heredoc spéciale qui supprime les tabulations au début de toutes les lignes: "<< -" (remarquez le tiret ajouté)
http://tldp.org/LDP/abs/html/here-docs.html
Exemple 19-4. Message multiligne, avec onglets supprimés
Vous pouvez l'utiliser comme ceci:
Résultat :
Cela ne fonctionne qu'avec des onglets, pas d'espaces.
la source
\t
fonctionne très bien si vous avez besoin d'onglets. Il suffit d'utiliserecho -e "$v"
plutôt queecho "$v"
d'activer les caractères antislashLaissez la coquille dévorer les sauts de ligne et les espaces suivants:
Donc c'est possible ... mais bien sûr, c'est une question de goût d'aimer ou de ne pas aimer cette solution ...
la source
Peut-être que vous pouvez essayer ceci.
la source
Voici comment je vous suggère de le faire, et je vais expliquer pourquoi, mais je veux d'abord parler d'autre chose ...
Beaucoup des autres solutions proposées ici semblent suggérer que vous pouvez modifier le contenu d'une variable shell en modifiant vos méthodes d'extension. Je peux vous assurer que ce n'est pas le cas.
SORTIE
Ce que vous voyez ci-dessus est d'abord un développement par division de champ, puis un rapport sur le nombre d'octets pour la variable source du développement, puis un développement délimité par des guillemets et le même nombre d'octets. Bien que la sortie puisse différer, le contenu de la variable shell
$string
ne change jamais, sauf lors de l'affectation.De plus, si vous ne comprenez pas pourquoi, il est certain que vous rencontrerez de très mauvaises surprises le plus tôt possible. Essayons encore, mais dans des conditions légèrement différentes.
Même
$string
- environnement différent.SORTIE
La division de champ se produit en fonction des délimiteurs de champ définis dans
$IFS
. Il existe deux types de délimiteurs: les$IFS
espaces et$IFS
tout le reste. Par défaut,$IFS
l’ espace de valeur newline est affecté à l’ espace de valeur - qui sont les trois$IFS
valeurs d’espace possibles . Comme vous pouvez le constater ci-dessus, il est facile à modifier et peut avoir des effets considérables sur les développements en division de champ.$IFS
les espaces blancs vont élider par séquence en un seul champ - et c’est pourquoiecho
un développement contenant une séquence d’espaces$IFS
contenant un espace n’évaluera qu’un seul espace - carecho
concatène ses arguments sur des espaces. Mais toutes les valeurs non-blancs ne sera pas Elide de la même manière, et chaque delimiter se produit obtient toujours un champ à elle - même - comme on peut le voir dans la substance d' expansion ci - dessus.Ce n'est pas le pire. Considérez cet autre
$string
.SORTIE
Ça a l'air d'accord, non? Eh bien, modifions à nouveau l'environnement.
SORTIE
Woah.
Par défaut, le shell développera les fichiers de noms de fichiers globs s'il peut leur correspondre. Cela se produit après le développement des paramètres et la division de champs dans son ordre d'analyse, de sorte que toute chaîne non mise entre guillemets est vulnérable de cette manière. Vous pouvez désactiver ce comportement
set -f
si vous le souhaitez, mais tout shell compatible POSIX sera toujours glob par défaut.C’est le genre de choses que vous rencontrez lorsque vous déposez des guillemets sur des extensions en fonction de vos préférences d’indentation. Et même ainsi, dans tous les cas, quel que soit son comportement d'expansion, la valeur réelle de
$string
reste identique à ce qu'elle était lors de la dernière affectation. Revenons donc à la première chose.SORTIE
Je pense que c'est un moyen beaucoup plus sain d'adapter la syntaxe du shell à vos préférences d'indentation. Ce que je fais ci-dessus consiste à affecter chaque chaîne individuelle à un paramètre de position - qui peut être référencé par un numéro comme
$1
ou${33}
-, puis à attribuer ses valeurs concaténées à l'$var
aide du paramètre shell spécial$*
.Cette approche n’est cependant pas à l’abri
$IFS
. Néanmoins, je considère que sa relation avec$IFS
un avantage supplémentaire à cet égard. Considérer:SORTIE
Comme vous pouvez le constater,
$*
concatène chaque argument dans"$@"
le premier octet$IFS
. Ainsi, enregistrer sa valeur pendant qu'elle$IFS
est affectée différemment donne différents délimiteurs de champs pour chaque valeur enregistrée. Ce que vous voyez ci-dessus est la valeur littérale de chaque variable, au fait. Si vous ne vouliez pas de délimiteur, vous feriez:SORTIE
la source
Vous voudrez peut-être essayer:
ou
et aussi vous pouvez vérifier cela .
la source
Utiliser une extension de substitution Bash
Si vous utilisez Bash, vous pouvez utiliser une extension de substitution . Par exemple:
la source
Ceci est une variante pour définir des variables de type chemin:
Utilisation des
set
écrasements$@
, qui peuvent être enregistrés et utilisés ultérieurement comme suit:La
LD_LIBRARY_PATH=$(sed 's/ :/:/g' <<< $LD_LIBRARY_PATH)
ligne élimine les espaces avant les deux points ainsi que les éventuels espaces de fin. Si seulement éliminer les espaces de fin, utilisezLD_LIBRARY_PATH=${LD_LIBRARY_PATH%% }
plutôt.Toute cette approche est une variante de l'excellente réponse de mikeserv.
la source
N'ayez pas peur des caractères d'espaces. Supprimez-les simplement avant d’imprimer votre texte multiligne.
Sortie:
Pas besoin d'utiliser un
<<-
heredoc et de casser votre indentation de 4 espaces avec des caractères de tabulation.la source