Leerzeilen mit grep entfernen


164

Ich habe es grep -v '^$'unter Linux versucht und das hat nicht funktioniert. Diese Datei stammt aus einem Windows-Dateisystem.

Antworten:


300

Versuche Folgendes:

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

Die -eOption ermöglicht Regex-Muster für den Abgleich.

Die einfachen Anführungszeichen ^$machen es für Cshell. Andere Muscheln freuen sich über einfache oder doppelte Anführungszeichen.

UPDATE: Dies funktioniert bei mir für eine Datei mit Leerzeilen oder "allen Leerzeichen" (z. B. Windows-Zeilen mit Zeilenenden im Stil "\ r \ n"), während oben nur Dateien mit Leerzeilen und Zeilenenden im Unix-Stil entfernt werden:

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

Dieses egrep funktioniert nur für Dateien mit null oder 1 Leerzeichen in der Zeile, nicht für Dateien mit 2 oder mehr Leerzeichen. Veränderung ? zu *.
Ed Morton

4
Dies sollte sein grep -E -v, alles danach -ewird als Muster interpretiert.
Jazzpi

6
grep -v -e '^[[:space:]]*$' -e '^#' fileSie erhalten alle nicht leeren Zeilen ohne Kommentar in einer Skript- oder Konfigurationsdatei (oder einem beliebigen Dateityp, der das Hash-Zeichen für Kommentare verwendet).
Palswim

"Die -eOption ermöglicht Regex-Muster für den Abgleich." Das ist sehr irreführend . -eist eine (POSIX-) Definition für: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(aus dem Handbuch ). Grep erwartet standardmäßig bereits einen (einfachen) regulären Ausdruck. Für dieses Muster können Sie -eganz weglassen : grep -v '^[[:space:]]*$' foo.txt.
Yeti

73

Halte es einfach.

grep . filename.txt

1
Dies gibt mir alle Zeilen in der Datei
phuclv

2
@ LưuVĩnhPhúc Es sollten alle Zeilen in der Datei außer Leerzeilen ausgegeben werden.
Frej Connolly

2
Dies funktioniert für mich bei Dateien von einem Linux-basierten System, jedoch nicht bei Dateien von Windows. Vermutlich wegen Windows-Zeilenendezeichen.

Ich stimme dem zu, obwohl es das Problem des OP, eine Datei mit Windows-Zeilenenden zu behandeln, nicht ganz löst, aber da ich dieses Problem nicht habe, stellte sich heraus, dass dies die perfekte Lösung für mich ist.
David Z

1
Dies ist die perfekte Lösung. Einfach und unter Linux gearbeitet.
W00f

30

Verwenden:

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

Oder einfach nur awk:

awk 'NF' file

Wenn Sie nicht über dos2unix verfügen, können Sie Tools wie tr verwenden :

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

Das Programm dos2unix kann nicht gefunden werden. Ist das für Windows? Der Befehl ask funktioniert auch nicht.
Knoten Ninja

Fragen? Nein, das ist awk.
Bilderstürmer

Ein guter Punkt beim Konvertieren in Zeilenenden im UNIX-Stil, da sonst reguläre Ausdrücke möglicherweise nicht wie erwartet funktionieren. Hier hat nichts für mich funktioniert, bis ich die Zeilenenden konvertiert habe.
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

Ausführen des Code-

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

Um mehr darüber zu erfahren, wie / warum dies funktioniert, empfehle ich, sich über reguläre Ausdrücke zu informieren. http://www.regular-expressions.info/tutorial.html


2
Wie und warum funktioniert das? Ihre Antwort wäre viel besser, wenn Sie erklären könnten. Zum Beispiel stimmt Ihr regulärer Ausdruck mit dem Anfang der Zeichenfolge überein, dann mit einem oder mehreren Leerzeichen unter Verwendung des POSIX-Standards und dann mit dem Ende der Zeichenfolge, dh mit grep -v werden alle Zeilen entfernt, die nur Leerzeichen sind. Richtig? Was passiert, wenn keine Leerzeichen vorhanden sind? Es ist einfach ein Zeilenumbruch?
Ben

Wie mein Beispiel zeigt, wird sogar nur eine leere Zeile entfernt (die erste Zeile). Ich habe weitere Informationen hinzugefügt, hoffentlich hilft das. :)
Sepero

3

Ich bevorzuge die Verwendung egrep, obwohl Ihr Ansatz in meinem Test mit einer echten Datei mit Leerzeichen einwandfrei funktioniert hat (allerdings ohne Anführungszeichen in meinem Test). Das hat auch funktioniert:

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

Versuchte das. Leere Linien werden weiterhin angezeigt. Könnte dies daran liegen, dass die Datei in Windows erstellt wurde?
Knoten Ninja

3

Wenn Sie Sequenzen mit mehreren Leerzeilen in einer Zeile haben und nur eine Leerzeile pro Sequenz möchten, versuchen Sie es

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

cat -s unterdrückt wiederholte leere Ausgabezeilen.

Ihre Ausgabe würde von gehen

match1



match2

zu

match1

match2

Die drei Leerzeilen in der ursprünglichen Ausgabe würden komprimiert oder zu einer Leerzeile "zusammengedrückt".


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

2

Das gleiche wie die vorherigen Antworten:

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

Hier grep -ebedeutet die erweiterte Version von grep . '^ $' bedeutet, dass zwischen ^ (Zeilenanfang) und $ (Zeilenende) kein Zeichen steht. '^' und '$' sind Regex-Zeichen.

Der Befehl grep -vdruckt also alle Zeilen, die nicht mit diesem Muster übereinstimmen (keine Zeichen zwischen ^ und $).

Auf diese Weise werden leere Leerzeilen entfernt.


-ebedeutet nicht "die erweiterte Version von grep", vielleicht sind Sie verwirrt mit -E? Das Handbuch sagt deutlich, dass -enur explizit gesagt wird, dass ein Muster folgt. Da das Muster nicht mit einem Bindestrich beginnt und Sie ohnehin nur ein Muster definieren, können Sie es auch weglassen, da grep standardmäßig ein Regex-Muster erwartet: grep -v '^$' foo.txt(Keine Notwendigkeit für eine erweiterte Regex-Funktionalität). Erwähnenswert ist auch, dass dadurch nicht die Leerzeilen in der Datei entfernt werden, sondern nur die, die durch die Ausgabe geleitet werden. Für diesen Fall sed -iwäre das richtige Werkzeug.
Yeti

1

Ich habe mich sehr bemüht, aber das scheint zu funktionieren (vorausgesetzt, \rSie beißen hier):

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

Das funktioniert, wenn ich den ersten Teil durch die Ausgabe aus der Datei ersetze.
Knoten Ninja

0

Verwenden von Perl:

perl -ne 'print if /\S/'

\S bedeutet, dass nicht leere Zeichen übereinstimmen.


0

egrep -v "^ \ s \ s +"

egrep macht bereits Regex und das \ s ist ein Leerraum.

Das + dupliziert das aktuelle Muster.

Das ^ ist für den Anfang


0

Verwenden:

grep pattern filename.txt | uniq

uniqreduziert benachbarte Leerzeilen auf nur eine Leerzeile, entfernt sie jedoch nicht vollständig. Trotzdem versuche ich gerne, es so zu benutzen uniq. Wenn Sie zuerst sortieren, werden effektiv alle Leerzeilen entfernt, sodass nur eine übrig bleibt. Eine Neuanordnung der Zeilenreihenfolge ist jedoch möglicherweise nicht akzeptabel.
Zach Young

Guter Punkt. Dadurch werden auch wiederholte Zeilen verarbeitet. Ich denke, meine Lösung führt zu Fehlern.
Baitisj

0

Hier ist eine andere Möglichkeit, die weißen Linien und Linien, die mit dem #Zeichen beginnen, zu entfernen . Ich denke, dies ist sehr nützlich, um Konfigurationsdateien zu lesen.

[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

Es ist wahr, dass die Verwendung von grep -v -e '^ $' funktionieren kann, es werden jedoch keine Leerzeilen entfernt, die 1 oder mehr Leerzeichen enthalten . Ich fand, dass die einfachste und einfachste Antwort zum Entfernen von Leerzeilen die Verwendung von awk ist . Das Folgende ist ein bisschen modifiziert von den Awk-Jungs oben:

awk 'NF' foo.txt

Da diese Frage jedoch für die Verwendung von grep bestimmt ist, werde ich Folgendes beantworten:

grep -v '^ *$' foo.txt

Hinweis : Das Leerzeichen zwischen ^ und *.

Oder Sie können die \ s verwenden, um Leerzeichen wie folgt darzustellen:

grep -v '^\s*$' foo.txt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.