Existe-t-il une méthode pour imprimer une sortie multiligne (sortie unique) sur la même ligne?
Par exemple, si la sortie est:
abc
def
qwerty
Est-il possible d'imprimer:
abcdefqwerty
Existe-t-il une méthode pour imprimer une sortie multiligne (sortie unique) sur la même ligne?
Par exemple, si la sortie est:
abc
def
qwerty
Est-il possible d'imprimer:
abcdefqwerty
Réponses:
Vous pouvez supprimer toutes les occurrences de personnages d'un ensemble donné avec tr -d
. Pour supprimer le caractère de nouvelle ligne, utilisez:
tr -d '\n'
Comme toujours, vous pouvez utiliser la redirection d'entrée et de sortie et des canaux pour lire ou écrire dans des fichiers et d'autres processus.
Si vous souhaitez conserver la dernière nouvelle ligne, vous pouvez simplement l'ajouter à nouveau avec echo
ou printf '\n'
, par exemple:
cat file1 file2... | { tr -d '\n'; echo; } > output.txt
Plusieurs façons. Pour illustrer, j'ai enregistré votre exemple dans file
:
$ cat file | tr -d '\n'
abcdefqwerty$
$ cat file | perl -pe 's/\n//'
abcdefqwerty$
Cela supprime tous les caractères de nouvelle ligne, y compris le dernier. Vous pourriez plutôt vouloir faire:
$ printf "%s\n" "$(cat file | perl -pe 's/\n//')"
abcdefqwerty
$ printf "%s\n" "$(cat file | tr -d '\n')"
abcdefqwerty
Vous pouvez diriger votre sortie multiligne via awk
awk '{printf "%s",$0} END {print ""}'
ou utilisez sed
:
sed ':a;N;$!ba;s/\n//g'
$ echo -e "1\n2\n3\n4" | awk '{printf "%s",$0} END {print ""}'
1234
$ echo -e "1\n2\n3\n4" | sed ':a;N;$!ba;s/\n//g'
1234
Pour en savoir plus: supprimer le saut de ligne à l'aide d'AWK · serverfault.SE
Également your_command | paste -sd ''
qui préserve la nouvelle ligne de fin.
Si vous souhaitez utiliser Perl pour cela, vous pouvez utiliser sa chomp
fonction:
perl -pe chomp
Vous pouvez passer un ou plusieurs noms de fichiers comme arguments ultérieurs.
perl -pe chomp file1 file2 file3
Dans certains cas, vous ne souhaiterez peut-être pas le faire , mais vous pouvez à la place rediriger ou rediriger vers cette commande. (Ces capacités - et cette mise en garde - s'appliquent également à toute autre solution perl -p
ou perl -n
solution basée.)
Donc, si vous souhaitez traiter la sortie de l'exécution some-command
:
some-command | perl -pe chomp
C'est potentiellement plus rapide que la commande Perl dans la réponse de terdon . Les caractères de nouvelle ligne (représentés par \n
) n'apparaissent qu'à la fin des lignes dans cette situation - car ils sont ce que Perl utilise pour décider de la fin de chaque ligne. s/\n//
recherche dans toute la ligne des sauts de ligne, tout en supprimant chomp
simplement celle à la fin (le cas échéant, car la dernière ligne peut ou non en avoir une).
La performance n'est peut-être pas vraiment la principale raison de préférer chomp
. La perl
commande dans la réponse de terdon ne serait que légèrement plus lente, sauf si vous traitez un fichier énorme avec de très longues lignes. Et si vous avez besoin de vitesse, le chemin de David Foerster est probablement encore plus rapide. chomp
est cependant exactement le bon outil pour cela si vous utilisez Perl, et je pense que l'intention de chomp
est plus claire que celle de s/\n//
. En fin de compte, il n'y a probablement pas de réponse objective quant à la meilleure solution.
Cependant, je déconseille l'utilisation de la substitution de commandes ( $(
)
) juste pour garantir l'impression d'un retour à la ligne en fin de ligne. À moins que le texte que vous traitez soit court, cela risque d'être assez lent - il doit collecter tout le texte à la fois, puis l'imprimer - et cela rend votre commande plus difficile à comprendre. Au lieu de cela, vous pouvez faire ce que David Foerster a suggéré et exécuter echo
ou printf '\n'
après.
perl -pe chomp; echo
Si vous redirigez depuis ou (comme le montre David Foerster) la redirection à partir de cette commande, vous pouvez l'enfermer de {
;}
sorte que la sortie des deux commandes soit prise ensemble. Si vous l'imprimez simplement sur le terminal, vous pouvez l'exécuter exactement comme indiqué ci-dessus. Cela fonctionne même si vous canalisez ou redirigez vers la commande, car echo
/ printf '\n'
ne lit aucune entrée. Autrement dit, cela fonctionne:
some-command | perl -pe chomp; echo
Pendant que vous êtes ici, vous ne pouvez pas simplement supprimer {
;}
:
{ perl -pe chomp; echo; } | some-other-command
Ou, si vous préférez, vous pouvez faire perl
imprimer la nouvelle ligne finale elle-même. Comme les enfermant perl
et echo
commandes {
;}
, cette approche fonctionne même si vous êtes la tuyauterie ou redirigeant de (et, comme toutes les approches, cela fonctionne quand vous êtes tuyauterie à elle aussi):
perl -wpe 'chomp; END { print "\n" }'
Notez que la commande dans la réponse de terdon fonctionne également très bien avec ces méthodes d'impression du retour à la ligne final. Par exemple:
perl -pe 's/\n//'; echo
perl -pe 's/\n//; END { print "\n" }'
perl -wpe 'chomp; END { print "\n" }
est le même processus, un avantage mineur par rapport à l'ajout d'un écho
Utilisation de manière shell uniquement:
while IFS= read -r line || [ -n "$line" ]; do printf "%s" "$line"; done < inputfile.txt
Cette réponse a une solution au problème que vous essayez de créer: Pourquoi bash supprime-t-il \ n dans $ (fichier cat)?
Si vous tapez, cat myfile.txt
vous verrez:
abc
def
ghi
Mais si vous tapez, echo $(cat myfile.txt)
vous verrez:
abc def ghi
Notez que cette méthode insère un espace où se trouvaient auparavant les nouvelles lignes distinctes. Cela rend la sortie plus facile à lire mais n'adhère pas strictement à la portée de votre question.
Si vous utilisez Bash, vous pouvez le faire sans aucun outil externe.
x=($(echo line1; echo line2))
echo "${x[@]}"
Résultat:
line1 line2
La première commande transforme la sortie multiligne en un tableau, la seconde commande étend le tableau en plusieurs arguments sur une seule ligne.
printf
+cat
+perl
est beaucoup mieux géré via unperl -pe 's/\n//;END{printf "\n"}' input.txt
processus unique, pas de substitution de commande et de confusion avec des guillemets, et pas d'UUOC. Peut-être.