Usuń puste linie za pomocą grep


Odpowiedzi:


300

Spróbuj wykonać następujące czynności:

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

Ta -eopcja umożliwia dopasowywanie wzorców wyrażeń regularnych.

Pojedyncze cudzysłowy ^$sprawiają, że działa to w Cshell. Inne powłoki będą zadowolone z cudzysłowów pojedynczych lub podwójnych.

AKTUALIZACJA: Działa to dla mnie dla pliku z pustymi liniami lub „wszystkimi białymi znakami” (takimi jak linie okien z końcówkami linii w stylu „\ r \ n”), podczas gdy powyższe usuwa tylko pliki z pustymi liniami i końcówkami linii w stylu unixowym:

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

Ten egrep działałby tylko dla plików z zerową lub 1 spacją w wierszu, a nie dla plików z 2 lub więcej spacjami. Zmiana ? do *.
— Ed Morton,

4
Tak powinno być grep -E -v, wszystko później -ejest interpretowane jako wzorzec.
— jazzpi

6
grep -v -e '^[[:space:]]*$' -e '^#' filewyświetli wszystkie niepuste, nie będące komentarzami wiersze w skrypcie lub pliku konfiguracyjnym (lub dowolnym typie pliku, który używa znaku krzyżyka dla komentarzy).
— palswim

„Ta -eopcja umożliwia dopasowywanie wzorców regex”. To jest bardzo mylące . -ejest (POSIX-) definicją dla: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(z podręcznika ). Grep już domyślnie oczekuje (podstawowego) wyrażenia regularnego. Z tego wzoru, można pominąć -ew całości: grep -v '^[[:space:]]*$' foo.txt.
— Yeti

73

Nie komplikuj.

grep . filename.txt

1
to daje mi wszystkie linie w pliku
— phuclv

2
@ LưuVĩnhPhúc Powinien wypisać wszystkie wiersze w pliku z wyjątkiem pustych wierszy.
— Frej Connolly,

2
Działa to dla mnie na plikach z systemu Linux, ale nie na plikach z Windows. Prawdopodobnie z powodu znaków końca linii systemu Windows.

Głosuję za tym, mimo że nie do końca rozwiązuje to problem OP z obsługą pliku z zakończeniami linii Windows, ale ponieważ nie mam tego problemu, okazało się to dla mnie idealnym rozwiązaniem.
— David Z

1
To idealne rozwiązanie. Prosty i działający w systemie Linux.
— W00f

30

Posługiwać się:

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

Lub po prostu awk:

awk 'NF' file

Jeśli nie masz dos2unix, możesz użyć narzędzi takich jak tr :

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

Nie można znaleźć programu dos2unix. Czy to dla systemu Windows? polecenie ask też nie działa.
— węzeł ninja

zapytać? Nie, to jest awk.
— iconoclast

Dobra uwaga na temat konwersji na zakończenia linii w stylu UNIX, w przeciwnym razie wyrażenia regularne mogą nie działać zgodnie z oczekiwaniami. Nic tutaj nie działało, dopóki nie przekonwertowałem końcówek linii.
— 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

Uruchamianie kodu

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

Aby dowiedzieć się więcej o tym, jak / dlaczego to działa, polecam przeczytanie o wyrażeniach regularnych. http://www.regular-expressions.info/tutorial.html


2
Jak i dlaczego to działa? Twoja odpowiedź byłaby znacznie lepsza, gdybyś mógł to wyjaśnić. Na przykład, twoje wyrażenie regularne dopasowuje początek łańcucha, a następnie jedną lub więcej spacji przy użyciu standardu POSIX, a następnie koniec łańcucha, tj. Za pomocą grep -v usuwa wszystkie linie, które są tylko spacjami. Dobrze? Co się stanie, jeśli nie ma spacji; to po prostu znak nowej linii?
— Ben

Jak pokazuje mój przykład, usuwana jest nawet tylko pusta linia (pierwsza linia). Dodałem więcej informacji, więc mam nadzieję, że to pomoże. :)
— Sepero

3

Wolę używać egrep, chociaż w moim teście z oryginalnym plikiem z pustą linią twoje podejście działało dobrze (choć bez cudzysłowów w moim teście). To też zadziałało:

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

Próbowałem tego. Nadal są wyświetlane puste linie. Czy może to być spowodowane tym, że plik został utworzony w systemie Windows?
— węzeł ninja

3

Jeśli masz sekwencje wielu pustych wierszy w jednym rzędzie i chciałbyś mieć tylko jeden pusty wiersz na sekwencję, spróbuj

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

cat -s pomija powtarzające się puste wiersze wyjściowe.

Twój wynik będzie pochodził z

match1



match2

do

match1

match2

Trzy puste wiersze w oryginalnym wyniku byłyby skompresowane lub „ściśnięte” w jeden pusty wiersz.


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

2

To samo co poprzednie odpowiedzi:

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

Tutaj grep -eoznacza rozszerzoną wersję grep . „^ $” oznacza, że ​​nie ma żadnego znaku między ^ (początek wiersza) a $ (koniec wiersza). „^” i „$” to znaki wyrażenia regularnego.

Zatem polecenie grep -vwypisze wszystkie wiersze, które nie pasują do tego wzorca (brak znaków między ^ a $).

W ten sposób puste puste linie są eliminowane.


-enie oznacza "rozszerzonej wersji grepa", może jesteś zdezorientowany -E? Podręcznik wyraźnie mówi, że -epo prostu wyraźnie mówi, że następuje wzór. Ponieważ wzorzec nie zaczyna się od myślnika, a i tak definiujesz tylko jeden wzorzec, równie dobrze możesz go pominąć, ponieważ domyślnie grep oczekuje jednego wzorca wyrażenia regularnego: grep -v '^$' foo.txt(nie ma potrzeby korzystania z rozszerzonej funkcjonalności wyrażenia regularnego). Warto również wspomnieć, że nie eliminuje to pustych wierszy w pliku, a jedynie te, które są przesyłane potokiem przez wyjście. W takim przypadku sed -ibyłoby właściwym narzędziem.
— Yeti

1

Bardzo się starałem, ale to wydaje się działać (zakładając, że \rcię tu gryzie):

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

To działa, jeśli zastąpię pierwszą część danymi wyjściowymi z pliku.
— węzeł ninja

0

Korzystanie z Perla:

perl -ne 'print if /\S/'

\S oznacza dopasowywanie niepustych znaków.


0

egrep -v "^ \ s \ s +"

egrep już wykonuje regex, a \ s to biały znak.

Znak + powiela bieżący wzorzec.

^ Jest na początek


0

Posługiwać się:

grep pattern filename.txt | uniq

uniqzredukuje przylegające puste linie do jednej pustej linii, ale nie usuwa ich całkowicie. Mimo to lubię próbować tego używać uniq. Sortowanie w pierwszej kolejności skutecznie usunie wszystkie puste wiersze - pozostawiając tylko jeden, ale zmiana kolejności wierszy może być nie do przyjęcia.
— Zach Young,

Słuszna uwaga. Spowoduje to również zgniatanie powtarzających się linii. Myślę, że moje rozwiązanie wprowadza błędy.
— baitisj

0

Oto inny sposób na usunięcie białych linii i linii zaczynających się od #znaku. Myślę, że jest to przydatne do czytania plików konfiguracyjnych.

[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

Prawdą jest, że użycie grep -v -e '^ $' może działać, jednak nie usuwa pustych wierszy, które mają 1 lub więcej spacji . Odkryłem, że najłatwiejszą i najprostszą odpowiedzią na usuwanie pustych linii jest użycie awk . Poniższy fragment jest nieco zmodyfikowany w stosunku do facetów z awk powyżej:

awk 'NF' foo.txt

Ale ponieważ to pytanie dotyczy używania grep, odpowiem na następujące pytanie:

grep -v '^ *$' foo.txt

Uwaga : spacja między ^ i *.

Lub możesz użyć \ s do oznaczenia pustej przestrzeni w następujący sposób:

grep -v '^\s*$' foo.txt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.