Bash: elimina l'interruzione di riga finale dall'output


189

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:


251

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

Questo elimina TUTTE le nuove righe dall'output, non solo la nuova riga finale come richiesto dal titolo.
Cody A. Ray,

@ CodyA.Ray: Devi essere d'accordo, tuttavia, che la domanda descrive un comando specifico che produrrà solo una singola riga di output. Ho, tuttavia, aggiornato la mia risposta per soddisfare il caso più generale. HTH.
Steve,

3
Ciò sarebbe meglio se le opzioni corte fossero sostituite con opzioni lunghe. Le lunghe opzioni insegnano oltre alla funzione es tr --delete '\n'.
Elijah Lynn,

1
Ho anche fatto| tr -d '\r'
AlikElzin-Kilaka il

Vale la pena notare che la soluzione di sostituzione cmd potrebbe portare a una linea troppo lunga se il file è molto grande.
phk,

88

Senso unico:

wc -l < log.txt | xargs echo -n

24
Meglio:echo -n `wc -l log.txt`
Satya,

9
Perché eseguire l'esecuzione dei comandi nei backtick è meglio dell'uso di una pipe?
Matthew Schinckel,

2
Questi non solo rimuoveranno le nuove righe finali, ma comprimeranno anche qualsiasi spazio bianco consecutivo (più precisamente, come definito da 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.
musiphil,

14
Peggio ancora, se l'output inizia con -e, verrà interpretato come l'opzione per echo. È sempre più sicuro da usare printf '%s'.
musiphil,

1
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.
yyny,

14

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:]]}

1
Puoi anche usaretrailing_linebreak_removed=${testvar%?}
PairedPrototype l'

Si noti che se si utilizza la sostituzione dei comandi, non è necessario eseguire alcuna operazione per rimuovere le nuove righe finali. Bash lo fa già come parte della sostituzione dei comandi: gnu.org/software/bash/manual/html_node/…
Michael Burr

10

Se assegni il suo output a una variabile, bashelimina automaticamente gli spazi bianchi:

linecount=`wc -l < log.txt`

10
Le nuove righe finali vengono rimosse, per essere esatti. È la sostituzione dei comandi che li rimuove, non l'assegnazione delle variabili.
Chepner,

2
Ho visto in Cygwin bash lo spazio bianco finale non rimosso quando si utilizza $ (cmd / c echo% VAR%). In questo caso ho dovuto usare $ {var %% [[: space:]]}.
Andrey Taranov,

1
Nota: non è l'assegnazione variabile, ma l'espansione dell'espressione che rimuove le nuove righe.
Ciro Santilli 26 冠状 病 六四 事件 法轮功

10

printf ritaglia già la nuova riga finale per te:

$ printf '%s' $(wc -l < log.txt)

Dettaglio:

  • printf stamperà il contenuto al posto del %ssegnaposto della stringa.
  • Se non gli dici di stampare una riga ( %s\n), non lo farà.

7
Se si inseriscono doppie virgolette attorno al comando come "$(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.
Brent Bradburn,

2
Non è printf che sta spogliando la nuova linea qui, è la shell che lo sta facendo con il $( )costrutto. Ecco la prova:printf "%s" "$(perl -e 'print "\n"')"
Flimm,

Ancora una volta, vale la pena notare che la riga di comando risultante potrebbe diventare troppo lunga.
phk,

Questa è una soluzione conveniente con il suggerimento di @ nobar:$ printf '%s' "$(wc -l < log.txt)"
Ilias Karim

10

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+$//'

Suppongo che questa sia un'estensione GNU, Mac sednon fornisce -z.
Spidey,

7

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)

2
La variabile non è tecnicamente necessaria. echo -n $(wc -l < log.txt)ha lo stesso effetto.
Chepner,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.