Quando eseguo i comandi in Bash (o, per essere precisi, wc -l < log.txt
), l'output contiene un'interruzione di riga dopo di esso. Come posso liberarmene?
Quando eseguo i comandi in Bash (o, per essere precisi, wc -l < log.txt
), l'output contiene un'interruzione di riga dopo di esso. Come posso liberarmene?
Risposte:
Se l'output previsto è una riga singola , è possibile rimuovere semplicemente tutti i caratteri di nuova riga dall'output. Non sarebbe raro collegarsi all'utility 'tr' o su Perl se si preferisce:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
È inoltre possibile utilizzare la sostituzione dei comandi per rimuovere la nuova riga finale:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Si noti che non sono d'accordo con la decisione del PO di scegliere la risposta accettata. Credo che uno dovrebbe evitare di usare 'xargs' ove possibile. Sì, è un bel giocattolo. No, non ne hai bisogno qui.
Se l'output previsto può contenere più righe , è necessario prendere un'altra decisione:
Se si desidera rimuovere MULTIPLI caratteri di nuova riga dalla fine del file, utilizzare nuovamente la sostituzione cmd:
printf "%s" "$(< log.txt)"
Se vuoi rimuovere rigorosamente L'ULTIMO carattere di nuova riga da un file, usa Perl:
perl -pe 'chomp if eof' log.txt
Nota che se sei sicuro di avere un carattere di nuova riga finale che vuoi rimuovere, puoi usare 'head' dai coreutils GNU per selezionare tutto tranne l'ultimo byte. Questo dovrebbe essere abbastanza veloce:
head -c -1 log.txt
Inoltre, per completezza, puoi verificare rapidamente dove sono i tuoi nuovi caratteri (o altri caratteri speciali) nel tuo file usando 'cat' e il flag 'show-all'. Il carattere del simbolo del dollaro indicherà la fine di ogni riga:
cat -A log.txt
tr --delete '\n'
.
| tr -d '\r'
Senso unico:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS
) in uno spazio. Esempio: echo "a b" | xargs echo -n
; echo -n $(echo "a b")
. Questo può o meno essere un problema per il caso d'uso.
-e
, verrà interpretato come l'opzione per echo
. È sempre più sicuro da usare printf '%s'
.
xargs
è molto lento sul mio sistema (e sospetto che lo sia anche su altri sistemi), quindi printf '%s' $(wc -l log.txt)
potrebbe essere più veloce, poiché di printf
solito è incorporato (anche perché non c'è reindirizzamento delle informazioni). Non usare mai i backtick, sono stati deprecati nelle versioni POSIX più recenti e presentano numerosi inconvenienti.
C'è anche il supporto diretto per la rimozione degli spazi bianchi nella sostituzione delle variabili di Bash :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Se assegni il suo output a una variabile, bash
elimina automaticamente gli spazi bianchi:
linecount=`wc -l < log.txt`
printf ritaglia già la nuova riga finale per te:
$ printf '%s' $(wc -l < log.txt)
Dettaglio:
%s
segnaposto della stringa. %s\n
), non lo farà."$(command)"
, le nuove righe interne verranno conservate e verrà rimossa solo la nuova riga finale . La shell sta facendo tutto il lavoro qui - printf
è solo un modo per riportare i risultati della sostituzione dei comandi stdout
.
$( )
costrutto. Ecco la prova:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Se si desidera rimuovere solo l'ultima riga , passare attraverso:
sed -z '$ s/\n$//'
sed
non aggiungerà a \0
alla fine dello stream se il delimitatore è impostato su NUL
via -z
, mentre per creare un file di testo POSIX (definito per terminare in a \n
), produrrà sempre un finale \n
senza-z
.
Per esempio:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
E per dimostrare di non aver NUL
aggiunto:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Per rimuovere più newline finali , passare attraverso:
sed -Ez '$ s/\n+$//'
sed
non fornisce -z
.
Se vuoi stampare l'output di qualcosa in Bash senza fine riga, lo fai eco con il -n
interruttore.
Se lo hai già in una variabile, fai eco con la nuova riga finale ritagliata:
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Oppure puoi farlo in una riga, invece:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
ha lo stesso effetto.