Pourquoi la commande suivante n'insère-t-elle pas de nouvelles lignes dans le fichier généré et quelle est la solution?
$ echo "Line 1\r\nLine2" >> readme.txt
$ cat readme.txt
Line 1\r\nLine2
echo
Une implémentation echo
qui est strictement conforme à la spécification Unix unique ajoutera des nouvelles lignes si vous le faites:
echo 'line1\nline2'
Mais ce n'est pas un comportement fiable. En fait, il n'y a vraiment pas tout comportement standard que vous pouvez attendre de echo
.
string
Une chaîne à écrire sur la sortie standard. Si le premier opérande est
-n
, Ou si l'un des opérandes contient une barre oblique inversée <\
>, le les résultats sont définis par l'implémentation.Sur les systèmes conformes XSI , si le premier opérande est
-n
, Il doit être traité comme une chaîne, pas une option. Les séquences de caractères suivantes doivent être reconnues sur les systèmes conformes à XSI dans l'un des arguments:
\a
- Écrivez un <alert>.
\b
- Écrivez un <backspace>.
\c
- Supprimez le <newline> qui suit sinon l'argument final dans la sortie. Tous les caractères suivant le\c
Dans les arguments doivent être ignorés.
\f
- Écrivez un <form-feed>.
\n
- Écrivez un <newline>.
\r
- Écrivez un <carriage-return>.
\t
- Écrivez un <tab>.
\v
- Écrivez un <table-tab>>.
\\
- Écrivez un caractère <backslash>.
\0num
- Écrivez une valeur de 8 bits qui est le nombre octal zéro, un, deux ou trois chiffresnum
.
Et donc il n'y a vraiment aucun moyen général de savoir comment écrire une nouvelle ligne avec echo
, sauf que vous pouvez généralement compter simplement sur echo
pour le faire.
Un shell bash
est généralement conforme à la spécification pas et gère le -n
Et d'autres options, mais même cela est incertain. Tu peux faire:
shopt -s xpg_echo
echo hey\\nthere
hey
there
Et pas même ça est nécessaire si bash
a été construit avec l'option build-time ...
Faites en sorte que le caractère intégré
echo
développe les caractères d'échappement avec barre oblique inverse par défaut, sans nécessiter l'option-e
. Ceci définit la valeur par défaut de l'option Shellxpg_echo
suron
, ce qui rend le Bashecho
se comportent plus comme la version spécifiée dans la spécification Unix unique, version 3. Voir Bash Builtins , pour une description des séquences d'échappement reconnues parecho
.
printf
En revanche, le comportement de printf
est assez docile en comparaison.
L'utilitaire
printf
a été ajouté pour fournir des fonctionnalités qui étaient historiquement fournies parecho
. Cependant, en raison de différences inconciliables dans les différentes versions deecho
existantes, la version a peu de fonctionnalités spéciales, laissant celles-ci à cette nouvelleprintf
, qui est basé sur un dans le système de la neuvième édition.La section DESCRIPTION ÉTENDUE correspond presque exactement à la fonction
printf()
dans la norme ISO C, bien qu'elle soit décrite en termes de notation de format de fichier dans Notation du format de fichier XBD .
Il gère les chaînes de format qui décrivent ses arguments - ce qui peut être un certain nombre de choses, mais pour les chaînes sont à peu près soit des chaînes %b
Yte, soit des chaînes littérales %s
. À part les %f
Ormats du premier argument, il se comporte le plus comme un argument de chaîne %b
Yte, sauf qu'il ne gère pas l'échappement \c
.
printf ^%b%s$ '\n' '\n' '\t' '\t'
^
\n$^ \t$
Voir Pourquoi printf
est-il meilleur que echo
? pour en savoir plus.
echo() printf
Vous pourriez écrire vos propres normes conformes echo
comme ...
echo(){
printf '%b ' "$@\n\c"
}
... qui devrait à peu près toujours faire la bonne chose automatiquement.
En fait, non ... Cela affiche un littéral \n
À la fin des arguments si le dernier argument se termine par un nombre impair de <backslashes>.
Mais cela ne veut pas:
echo()
case ${IFS- } in
(\ *) printf %b\\n "$*";;
(*) IFS=\ $IFS
printf %b\\n "$*"
IFS=${IFS#?}
esac
Passez le drapeau -e à echo pour qu'il analyse les caractères échappés tels que "\ r\n", comme ceci:
echo -e "Line 1\r\nLine2" >> readme.txt
Dans toutes les versions de bash que j'ai utilisées, vous pouvez simplement insérer un saut de ligne littéral dans une chaîne de manière interactive ou dans un script, à condition que la chaîne soit suffisamment citée.
Interactivement:
$ echo "Line one
> Line two"
Line one
Line two
$
Dans un script:
echo "Line one
Line two"
echo -e "Line 1\r\nLine2" >> readme.txt
autres possibilités d'utilisation:
man echo
Les gens ont déjà répondu adéquatement, mais je refuse d'accepter un monde où l'écho accepte toute option autre que -n
.
nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3
Si vous avez un personnage qui ne fait pas partie du message, vous pouvez passer par sed
$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
Utilisation
echo -e "line1\nline2"
Cela imprimera une nouvelle ligne.