Lorsque j'exécute des commandes dans Bash (ou pour être plus précis wc -l < log.txt
), la sortie contient un saut de ligne après. Comment m'en débarrasser?
Lorsque j'exécute des commandes dans Bash (ou pour être plus précis wc -l < log.txt
), la sortie contient un saut de ligne après. Comment m'en débarrasser?
Réponses:
Si votre sortie attendue est une seule ligne , vous pouvez simplement supprimer tous les caractères de nouvelle ligne de la sortie. Il ne serait pas rare de diriger vers l'utilitaire 'tr', ou vers Perl si vous préférez:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
Vous pouvez également utiliser la substitution de commande pour supprimer la nouvelle ligne de fin:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Veuillez noter que je ne suis pas d'accord avec la décision du PO de choisir la réponse acceptée. Je pense qu'il faut éviter d'utiliser «xargs» lorsque cela est possible. Oui, c'est un jouet sympa. Non, vous n'en avez pas besoin ici.
Si votre sortie attendue peut contenir plusieurs lignes , vous avez une autre décision à prendre:
Si vous souhaitez supprimer MULTIPLES caractères de nouvelle ligne à la fin du fichier, utilisez à nouveau la substitution cmd:
printf "%s" "$(< log.txt)"
Si vous souhaitez supprimer strictement LE DERNIER caractère de nouvelle ligne d'un fichier, utilisez Perl:
perl -pe 'chomp if eof' log.txt
Notez que si vous êtes certain d'avoir un caractère de fin de ligne à supprimer, vous pouvez utiliser «head» de GNU coreutils pour tout sélectionner sauf le dernier octet. Cela devrait être assez rapide:
head -c -1 log.txt
De plus, pour être complet, vous pouvez rapidement vérifier où se trouvent vos caractères de nouvelle ligne (ou autres caractères spéciaux) dans votre fichier en utilisant «cat» et l'indicateur «show-all». Le caractère signe dollar indiquera la fin de chaque ligne:
cat -A log.txt
tr --delete '\n'
.
| tr -d '\r'
Une manière:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS
) à un espace. Exemple echo "a b" | xargs echo -n
:; echo -n $(echo "a b")
. Cela peut ou non être un problème pour le cas d'utilisation.
-e
, elle sera interprétée comme l'option de echo
. C'est toujours plus sûr à utiliser printf '%s'
.
xargs
est très lent sur mon système (et je soupçonne que c'est aussi sur d'autres systèmes), donc printf '%s' $(wc -l log.txt)
peut-être plus rapide, car il printf
s'agit généralement d'une fonction intégrée (également parce qu'il n'y a pas de redirection d'informations). N'utilisez jamais de backticks, ils sont obsolètes dans les nouvelles versions de POSIX et présentent de nombreux inconvénients.
Il existe également un support direct pour la suppression des espaces blancs dans la substitution de variables Bash :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Si vous affectez sa sortie à une variable, bash
supprime automatiquement les espaces:
linecount=`wc -l < log.txt`
printf coupe déjà la nouvelle ligne de fin pour vous:
$ printf '%s' $(wc -l < log.txt)
Détail:
%s
espace réservé à la chaîne. %s\n
), ce ne sera pas le cas."$(command)"
, les retours à la ligne internes seront conservés - et seul le retour à la ligne de fin sera supprimé. Le shell fait tout le travail ici - printf
c'est juste un moyen de renvoyer les résultats de la substitution de commande vers stdout
.
$( )
construction. Voici la preuve:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Si vous souhaitez supprimer uniquement la dernière nouvelle ligne , passez par:
sed -z '$ s/\n$//'
sed
n'ajoutera pas \0
de fin à puis du flux si le délimiteur est défini sur NUL
via -z
, alors que pour créer un fichier texte POSIX (défini pour se terminer par a \n
), il produira toujours un final \n
sans-z
.
Par exemple:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
Et pour prouver non NUL
ajouté:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Pour supprimer plusieurs nouvelles lignes de fin , passez par:
sed -Ez '$ s/\n+$//'
sed
ne fournit pas -z
.
Si vous voulez imprimer la sortie de quoi que ce soit dans Bash sans fin de ligne, vous en faites l'écho avec le -n
commutateur.
Si vous l'avez déjà dans une variable, faites-en l'écho avec la nouvelle ligne de fin recadrée:
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Ou vous pouvez le faire en une seule ligne, à la place:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
a le même effet.