Zamiana wielu pustych linii na jedną pustą linię w vim / sed


42

Pytanie mniej więcej mówi wszystko. Wiem, że /^$/dusunie wszystkie puste linie, ale nie widzę, jak powiedzieć „zamień dwie lub więcej pustych linii na jedną pustą linię”

Jakieś pomysły?

Odpowiedzi:


48

Jeśli nie używasz vima ani seda do innych celów, cat faktycznie ma łatwy wbudowany sposób na zwijanie wielu pustych linii, po prostu użyj cat -s.

Jeśli byłeś już w vimie i chciałeś tam pozostać, możesz to zrobić za pomocą wewnętrznego wyszukiwania i zastąpić go, wydając: :%s!\n\n\n\+!^M^M!g(^ M to wizualna reprezentacja nowego wiersza, możesz wprowadzić go, naciskając Ctrl+ vEnter), lub ocalić siebie wpisując po prostu łuskanie obecnie do kota: :%!cat -s.


wow, nie znałem -sopcji cat - tylko historyczna notatka, nie ma jej w POSIX, ale wydaje się być dostępna w BSD i GNU cat.
maxschlepzig

2
Oznaczanie jako „wygrywające” dla :%!cat -s. Naucz się czegoś GNnew każdego dnia!
Andrew Bolster,

3
Myślę, że możesz także użyć \ r zamiast ^ M w ten sposób:%s!\n\n\n\+!\r\r!g
Niko Bellic

Potrzebowałem tego dzisiaj. Dziękuję Caleb! :)
Dɑvïd

19

Użyj, \naby wskazać nową linię we wzorcu wyszukiwania. Użyj Ctrl+ Mw tekście zastępczym lub odnośniku wstecznym. Zobacz :help patterni :help sub-replace-special(link z :help :s).

%s/\(\n\n\)\n\+/\1/

Czy możesz wyjaśnić, w jaki sposób wzorzec wyszukiwania?
Sagar Jain,

@sjmp Wymagania: zamień dwie lub więcej pustych linii na jedną pustą linię. Wdrożenie: zastąp trzy lub więcej kolejnych nowych linii tylko dwoma nowymi liniami. Objaśnienie konstrukcji używanych w poleceniu znajduje się w instrukcji.
Gilles „SO- przestań być zły”

Ale dlaczego musisz używać grupy, gdy jej zawartość jest naprawiona?
Sabuncu

@Sabuncu Nie musisz używać grupy. Ale dlaczego nie skorzystać z grupy? Tutaj użyłem grupy, ponieważ nie możesz skopiować i wkleić polecenia z nowym wierszem w tekście zastępczym: musisz wstawić literalny znak Ctrl + M, \nnie działa w tekście zastępczym.
Gilles 'SO - przestań być zły'

Teraz rozumiem, dziękuję za poświęcenie czasu na odpowiedź.
Sabuncu

6

Jeśli w Vimie, po prostu zrób to:

:%!cat -s

2
Możesz dodać trochę szczegółów na temat tego, jak to działa, nawet jeśli jest to tylko cytat ze manstrony.
jasonwryan

Nie działał w
systemie

0

Za pomocą Perla:

perl -00 -pe ''

-00 opcja wiersza poleceń włącza tryb slurp akapitowy, co oznacza, że ​​Perl czyta tekst akapit po akapicie, a nie linia po linii.


0

Z sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE

-2

Wiem, że to głupi kod, ale chciałem rozwiązać ten problem w niecałe 10 minut i zadziałało

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done

1
uniqusuwa sąsiednie równe linie. Nie tego chce OP.
pacholik

@ Pacholik wyraźnie powiedział „Zastąpienie wielu pustych linii pojedynczą pustą linią” NIE usuwa sąsiednich równych linii !!!
Mahmoud Zalt

3
Tak, dokładnie ...
pacholik
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.