Mam dokument z wieloma pustymi wierszami.
Jak mogę je usunąć, gdy są razem 2 lub więcej.
Próbowałem sed "s/\n\n//"
pliku, ale to nie działało. Żaden błąd.
Mam dokument z wieloma pustymi wierszami.
Jak mogę je usunąć, gdy są razem 2 lub więcej.
Próbowałem sed "s/\n\n//"
pliku, ale to nie działało. Żaden błąd.
Odpowiedzi:
Aby usunąć puste linie:
sed '/^$/d'
sed
jest zorientowany na linię, więc myślenie w kategoriach „2 lub więcej określonego bajtu” działa, z wyjątkiem sytuacji, gdy ten bajt jest znakiem nowej linii. Następnie musisz wymyślić coś, co zadziała dla całej linii.
sed
jest w stanie obsłużyć kilka linii za pomocą funkcji „przestrzeni wzorów” / „przestrzeni trzymania” Ale czuję, że to zbyt skomplikowane. ;-)
1!
(mecz wszystko z wyjątkiem linii nr 1), w następujący sposób: sed '1!{/^$/d'}
.
sed
. Utworzenie pliku spowoduje usunięcie dowolnego istniejącego pliku o tej samej nazwie. sed '/^&/d' file.txt > otherfile.txt
będzie działać.
Nie ma potrzeby sed
. grep
zrobi:
grep .
(to grep
znaczy SPC, kropka, czyli pasuje do dowolnej linii zawierającej co najmniej jeden znak).
Jest także:
tr -s '\n'
(ściśnij dowolną sekwencję znaków nowej linii w jedną).
Jak zauważył Chris, oba nie są równoważne, ponieważ usuwanie pustych linii (jak pierwsze rozwiązanie powyżej i większość innych odpowiedzi skupia się tutaj) nie jest tym samym, co ściskanie sekwencji znaków nowego wiersza zgodnie z żądaniem w przypadku, gdy pierwszy wiersz jest pusty, ponieważ zajmuje tylko jeden wiodący znak nowej linii, aby pierwszy wiersz był pusty.
Widząc @Bruce EDIGER za odpowiedź sed
nie jest najlepszym narzędziem do tego, ponieważ jest oparty na linii i traktuje \n
jako znak końca linii, co komplikuje się.sed
może okazać się doskonałym narzędziem do pracy, nadal, oto niektóre inne opcje:
Perl
perl -ne 'print if /./' file.txt
lub
perl -pe '$/=""; s/\n+/\n/;' file.txt
Dzięki @ruakh, który zmusił mnie do przeczytania tego :
$ /
Separator rekordów wejściowych, domyślnie nowy wiersz. Wpływa to na wyobrażenie Perla o tym, czym jest „linia”. Działa jak zmienna RS awk, włączając traktowanie pustych linii jako terminatora, jeśli jest ustawiony na ciąg pusty (pusty wiersz nie może zawierać spacji ani tabulatorów). Możesz ustawić ciąg znaków składający się z wielu znaków, aby dopasować terminator zawierający wiele znaków lub cofnąć, aby odczytać koniec pliku. Ustawienie go na „\ n \ n” oznacza coś nieco innego niż ustawienie na „”, jeśli plik zawiera kolejne puste wiersze. Ustawienie „” potraktuje dwie lub więcej następujących po sobie pustych linii jako pojedynczą pustą linię. Ustawienie na „\ n \ n” będzie ślepo zakładać, że następny znak wejściowy należy do następnego akapitu, nawet jeśli jest to nowy wiersz.
gawk / awk
awk '$1' file.txt
Będzie to działać w opublikowanym przykładzie, ale jak wskazał @Stephane Chazelas , usunie również wiersze, których pierwsze pole „wygląda” 0
. Jest to bardziej niezawodne:
awk NF file.txt
perl -pe 's/\n+/\n/ file.txt
separator rekordów wejściowych nie ma znaczenia dla tego zastosowania.
perl -pe
lub perl -ne
praca linia po linii. \n+
nigdy nie będzie pasować, ponieważ jest stosowany tylko w jednym wierszu. Dlatego trzeba albo ustawić $/
lub użyj -0
ti slurp plik całości: perl -0pe 's/\n+/\n/' file
.
Co masz na myśli usunąć? usunąć duplikat (wiele pustych wierszy do jednego) czy usunąć wszystkie?
Jeśli chcesz usunąć duplikat, oto metoda wykorzystująca sed:
sed '$!N; /^\(.*\)\n\1$/!P; D'
Symuluje uniq
polecenie.
Najlepszym wyborem jest użycie awk
:
awk NF <filename>
sed
część działa świetnie! Polecając ten jako najlepszą odpowiedź.
W przypadku większości tych odpowiedzi należy najpierw usunąć końcowe białe znaki. Usunięcie podwójnych linii nowych usuwa wszystkie puste linie. (Pomyśl o tym).
Dosłownie zinterpretowana OP chce „usunąć wszystkie puste linie z pliku, jeśli występują powtarzające się puste linie”.
Typowy użytkownik chce „usunąć tylko zduplikowane puste linie”.
Aby to zrobić, najpierw usuń końcowe białe spacje i potokuj przez cat -s
sed s/[[:space:]]*$// | cat -s
A jednak nie usunie to zbędnej początkowej lub końcowej pustej linii.
Jeśli chcesz zachować jedną pustą linię dla dowolnej sekwencji pustych linii, możesz:
sed -e '/./b' -e :n -e 'N;s/\n$//;tn'
cat -s
), która faktycznie spełnia dokładnie to pytanie, jakie rozumiem. (I to jest lepsze niż cat -s
dlatego, że mogę sed -i
z tym korzystać.)
Spróbuj sed -e 's#\\n\\n#\\n#g' input.file > output.file
użyć /
obu jako separatora pól, a część wyrażenia regularnego może być problemem.
Użyj tego polecenia:
tr -s '\r' '\n'
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. Polecenie tr
przetłumaczy wszystko \r
na, \n
a następnie ścisnie wszystko \n
do jednego. Więc działa, nie wiem, co zrobić z faktem, że dotyczy to systemu Windows, a nie UNIX.