Rimuovi le righe vuote con grep


164

Ho provato grep -v '^$'su Linux e non ha funzionato. Questo file proviene da un file system di Windows.

Risposte:


301

Prova quanto segue:

grep -v -e '^$' foo.txt

L' -eopzione consente schemi regex per la corrispondenza.

Le virgolette singole in giro lo ^$fanno funzionare per Cshell. Altre shell saranno felici con virgolette singole o doppie.

AGGIORNAMENTO: Questo funziona per me per un file con righe vuote o "tutto lo spazio bianco" (come le righe di Windows con terminazioni di riga di stile "\ r \ n"), mentre quanto sopra rimuove solo i file con righe vuote e terminazioni di riga di stile unix:

grep -v -e '^[[:space:]]*$' foo.txt

Quel egrep funzionerebbe solo per file con zero o 1 spazio sulla linea, non per file con 2 o più spazi. Modificare ? per *.
Ed Morton,

4
Questo dovrebbe essere grep -E -v, tutto ciò che -eviene interpretato come modello.
jazzpi,

6
grep -v -e '^[[:space:]]*$' -e '^#' filefornirà tutte le righe non vuote e non di commento in uno script o in un file di configurazione (o qualsiasi tipo di file che utilizza il carattere hash per i commenti).
palswim,

"L' -eopzione consente schemi regex per la corrispondenza." Questo è molto fuorviante . -eè una definizione (POSIX-) per: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(dal manuale ). Grep prevede già un'espressione regolare (di base) per impostazione predefinita. Per questo motivo, si può lasciare fuori -etutto: grep -v '^[[:space:]]*$' foo.txt.
Yeti

74

Mantienilo semplice.

grep . filename.txt

1
questo mi dà tutte le righe nel file
phuclv

2
@ LưuVĩnhPhúc Dovrebbe produrre tutte le righe del file tranne le righe vuote.
Frej Connolly,

2
Questo funziona per me su file da un sistema basato su Linux ma non su file da Windows. Presumibilmente a causa dei caratteri di fine riga di Windows.

Sto votando questo anche se non risolve del tutto il problema dell'OP di gestire un file con terminazioni di linea di Windows, ma poiché non ho questo problema, questa si è rivelata la soluzione perfetta per me.
David Z,

1
Questa è la soluzione perfetta. Semplice e lavorato su Linux.
W00f,

30

Uso:

$ dos2unix file
$ grep -v "^$" file

O semplicemente awk:

awk 'NF' file

Se non hai dos2unix, puoi usare strumenti come tr :

tr -d '\r' < "$file" > t ; mv t "$file"

Impossibile trovare il programma dos2unix. È quello per Windows? il comando ask non funziona neanche.
nodo ninja

Chiedi? No, quello è awk.
iconoclasta,

Un buon punto per la conversione in terminazioni di linea in stile UNIX, altrimenti le espressioni regolari potrebbero non funzionare come previsto. Niente qui ha funzionato per me fino a quando non ho convertito i finali di linea.
Ryan H.

16
grep -v "^[[:space:]]*$"

The -v makes it print lines that do not completely match

===Each part explained===
^             match start of line
[[:space:]]   match whitespace- spaces, tabs, carriage returns, etc.
*             previous match (whitespace) may exist from 0 to infinite times
$             match end of line

Esecuzione del codice

$ echo "
> hello
>       
> ok" |
> grep -v "^[[:space:]]*$"
hello
ok

Per capire di più su come / perché funziona, consiglio di leggere le espressioni regolari. http://www.regular-expressions.info/tutorial.html


2
Come e perché funziona? La tua risposta sarebbe molto meglio se potessi spiegare. Ad esempio la tua espressione regolare corrisponde all'inizio della stringa quindi a uno o più spazi usando lo standard POSIX quindi alla fine della stringa, cioè con grep -v rimuove tutte le righe che sono solo spazi. Destra? Cosa succede se non ci sono spazi; è semplicemente un personaggio newline?
Ben

Come mostra il mio esempio, anche solo una riga vuota viene rimossa (la prima riga). Ho aggiunto ulteriori informazioni, quindi spero che questo aiuti. :)
Sepero

3

Preferisco usare egrep, anche se nel mio test con un file originale con una riga vuota il tuo approccio ha funzionato bene (anche se senza virgolette nel mio test). Anche questo ha funzionato:

egrep -v "^(\r?\n)?$" filename.txt

Ci ho provato. Le righe vuote continuano a essere visualizzate. Potrebbe essere perché il file è stato creato in Windows?
nodo ninja

3

Se hai sequenze di più righe vuote in una riga e desideri una sola riga vuota per sequenza, prova

grep -v "unwantedThing" foo.txt | cat -s

cat -s elimina le righe di output vuote ripetute.

Il tuo output verrebbe da

match1



match2

per

match1

match2

Le tre righe vuote nell'output originale verrebbero compresse o "compresse" in una riga vuota.


2
awk 'NF' file-with-blank-lines > file-with-no-blank-lines

2

Lo stesso delle risposte precedenti:

grep -v -e '^$' foo.txt

Qui, grep -esignifica la versione estesa di grep . '^ $' significa che non ci sono caratteri tra ^ (inizio riga) e $ (fine riga). '^' e '$' sono caratteri regex.

Quindi il comando grep -v stamperà tutte le righe che non corrispondono a questo modello (nessun carattere tra ^ e $).

In questo modo, vengono eliminate le righe vuote vuote.


-enon significa "la versione estesa di grep", forse sei confuso con -E? Il manuale dice chiaramente che -edice esplicitamente che segue un modello. Poiché il pattern non inizia con un trattino e si sta definendo comunque solo un pattern, è possibile lasciarlo fuori come per impostazione predefinita grep prevede un pattern regex: grep -v '^$' foo.txt(non è necessaria la funzionalità regex estesa). Inoltre, vale la pena ricordare che ciò non elimina le righe vuote nel file, ma solo ciò che viene inviato attraverso l'output. In tal caso, sed -isarebbe lo strumento giusto.
Yeti

1

Ho provato duramente, ma questo sembra funzionare (supponendo che \rti morda qui):

printf "\r" | egrep -xv "[[:space:]]*"

Funziona se sostituisco la prima parte con l'output del file.
nodo ninja

0

Utilizzando Perl:

perl -ne 'print if /\S/'

\S significa abbinare caratteri non vuoti.


0

egrep -v "^ \ s \ s +"

egrep fa già regex e il \ s è uno spazio bianco.

Il + duplica il modello corrente.

Il ^ è per l'inizio


0

Uso:

grep pattern filename.txt | uniq

uniqridurrà le righe vuote adiacenti a una sola riga vuota, ma non le rimuoverà completamente. Tuttavia, mi piace provare a usarlo in uniqquel modo. L'ordinamento per primo rimuove effettivamente tutte le righe vuote, lasciandone solo una, ma risistemare l'ordine delle righe potrebbe non essere accettabile.
Zach Young,

Buon punto. Ciò comporterà anche la ripetizione di righe. Immagino che la mia soluzione introduca dei bug.
Baitisj,

0

Ecco un altro modo per rimuovere le linee bianche e le linee che iniziano con il #segno. Penso che questo sia abbastanza utile per leggere i file di configurazione.

[root@localhost ~]# cat /etc/sudoers | egrep -v '^(#|$)'
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS"
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
stack ALL=(ALL) NOPASSWD: ALL

0

È vero che l'uso di grep -v -e '^ $' può funzionare, tuttavia non rimuove le righe vuote che contengono 1 o più spazi . Ho trovato la risposta più semplice e più semplice per rimuovere le righe vuote è l'uso di awk . Quello che segue è un po 'modificato dai ragazzi awk sopra:

awk 'NF' foo.txt

Ma poiché questa domanda è per usare grep, risponderò a quanto segue:

grep -v '^ *$' foo.txt

Nota : lo spazio vuoto tra ^ e *.

Oppure puoi usare \ s per rappresentare uno spazio vuoto come questo:

grep -v '^\s*$' foo.txt
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.