L'affectation ne supprime pas les caractères de nouvelle ligne, c'est en echo
fait cela. Vous devez simplement mettre des guillemets autour de la chaîne pour conserver ces nouvelles lignes:
echo "$testvar"
Cela donnera le résultat souhaité. Consultez la transcription suivante pour une démonstration:
pax> cat num1.txt ; x=$(cat num1.txt)
line 1
line 2
pax> echo $x ; echo '===' ; echo "$x"
line 1 line 2
===
line 1
line 2
La raison pour laquelle les retours à la ligne sont remplacés par des espaces n'est pas entièrement liée à la echo
commande, mais plutôt à une combinaison de choses.
Lorsqu'on lui donne une ligne de commande, la bash
divise en mots selon la documentation de la IFS
variable:
IFS: Le séparateur de champ interne qui est utilisé pour la division de mot après l'expansion ... la valeur par défaut est <space><tab><newline>
.
Cela spécifie que, par défaut, l'un de ces trois caractères peut être utilisé pour diviser votre commande en mots individuels. Après cela, les séparateurs de mots ont disparu, il ne vous reste plus qu'une liste de mots.
Combinez cela avec la echo
documentation (une bash
commande interne), et vous verrez pourquoi les espaces sont affichés:
echo [-neE] [arg ...]: Affiche les arguments , séparés par des espaces, suivis d'une nouvelle ligne.
Lorsque vous utilisez echo "$x"
, cela force la x
variable entière à être un seul mot selon bash
, par conséquent, il n'est pas divisé. Vous pouvez le voir avec:
pax> function count {
...> echo $#
...> }
pax> count 1 2 3
3
pax> count a b c d
4
pax> count $x
4
pax> count "$x"
1
Ici, la count
fonction affiche simplement le nombre d'arguments donnés. Les variantes 1 2 3
et le a b c d
montrent en action.
Ensuite, nous l'essayons avec les deux variantes de la x
variable. Celui sans guillemets montre qu'il ya quatre mots, "test"
, "1"
, "test"
et "2"
. L'ajout des guillemets en fait un seul mot "test 1\ntest 2"
.
Cela est dû à la variable IFS (Internal Field Separator) qui contient une nouvelle ligne.
Une solution de contournement consiste à réinitialiser IFS pour ne pas contenir la nouvelle ligne, temporairement :
Pour ANNULER cet horrible changement pour IFS:
la source
echo "$(IFS=''; cat text.txt)"
Bash -ge 4 a le mapfile intégré pour lire les lignes de l'entrée standard dans une variable de tableau.
Voir également:
http://bash-hackers.org/wiki/doku.php/commands/builtin/mapfile
la source
Juste si quelqu'un est intéressé par une autre option:
la source
Votre variable est correctement définie par
testvar=$(cat test.txt)
. Pour afficher cette variable composée de caractères de nouvelle ligne, ajoutez simplement des guillemets doubles, par exempleVoici l'exemple complet:
la source
L'
envdir
utilitaire fournit un moyen simple de le faire.envdir
utilise des fichiers pour représenter des variables d'environnement, avec des noms de fichiers mappés sur des noms de var env et un mappage de contenu de fichier sur des valeurs de var env. Si le contenu du fichier contient des retours à la ligne, env var.Voir https://pypi.python.org/pypi/envdir
la source