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 printfsolito è 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, bashelimina 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:
%ssegnaposto 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$//'
sednon aggiungerà a \0alla fine dello stream se il delimitatore è impostato su NULvia -z, mentre per creare un file di testo POSIX (definito per terminare in a \n), produrrà sempre un finale \nsenza-z .
Per esempio:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
E per dimostrare di non aver NULaggiunto:
$ { 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+$//'
sednon 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.