Ersetzen mehrerer Leerzeilen durch eine einzelne Leerzeile in vim / sed

42

Frage sagt mehr oder weniger alles. Mir ist bekannt, dass /^$/dalle Leerzeilen entfernt werden, aber ich kann nicht sagen, wie zwei oder mehr Leerzeilen durch eine einzelne Leerzeile ersetzt werden sollen.

Irgendwelche Ideen?

Andrew Bolster
quelle

Antworten:

48

Wenn Sie nicht für eine andere Verwendung vim oder sed feuern, hat cat tatsächlich eine einfache Möglichkeit, mehrere Leerzeilen zu kollabieren cat -s. Verwenden Sie einfach .

Wenn Sie bereits in vim waren und dort bleiben :%s!\n\n\n\+!^M^M!gmöchten, können Sie dies mit dem internen Suchen und Ersetzen tun, indem Sie Folgendes eingeben : (Das ^ M ist die visuelle Darstellung einer neuen Zeile. Sie können es eingeben, indem Sie Ctrl+ drücken. vEnter) Oder speichern Sie sich das Eingabe von nur Katze Beschuss aus: :%!cat -s.

Caleb
quelle
Wow, ich kannte die -sOption cat nicht - nur eine historische Anmerkung, sie ist nicht in POSIX enthalten, scheint aber in BSD und GNU cat verfügbar zu sein.
maxschlepzig
2
Als "gewinnend" für die :%!cat -s. Lerne jeden Tag etwas Neues!
Andrew Bolster
3
Ich denke, Sie können auch \ r anstelle von ^ M wie %s!\n\n\n\+!\r\r!g
folgt verwenden
Ich brauchte das heute. Vielen Dank, Caleb! :)
Dienstag,
19

Verwenden Sie \ndiese Option, um eine neue Zeile im Suchmuster anzugeben. Verwenden Sie Ctrl+ Mim Ersetzungstext oder einen Rückverweis. Siehe :help patternund :help sub-replace-special(verlinkt von :help :s).

%s/\(\n\n\)\n\+/\1/
Gilles 'SO - hör auf böse zu sein'
quelle
Können Sie bitte erklären, wie das Suchmuster funktioniert?
Sagar Jain
@sjmp Voraussetzung: Ersetzen Sie zwei oder mehr Leerzeilen durch eine Leerzeile. Implementierung: Ersetzen Sie drei oder mehr aufeinanderfolgende Zeilenumbrüche durch nur zwei Zeilenumbrüche. Im Handbuch finden Sie eine Erläuterung der im Befehl verwendeten Konstrukte.
Gilles 'SO - hör auf böse zu sein'
Aber warum müssen Sie eine Gruppe verwenden, wenn deren Inhalt festgelegt ist?
Sabuncu
@ Sabuncu Sie müssen keine Gruppe verwenden. Aber warum nicht eine Gruppe benutzen? In diesem Fall habe ich eine Gruppe verwendet, da Sie keinen Befehl mit einer neuen Zeile im Ersetzungstext kopieren und einfügen können: Sie müssen ein literales Strg + M-Zeichen einfügen, \ndas im Ersetzungstext nicht funktioniert.
Gilles 'SO- hör auf böse zu sein'
Jetzt verstehe ich, danke, dass Sie sich die Zeit genommen haben zu antworten.
Sabuncu
6

Wenn Sie in Vim sind, machen Sie einfach Folgendes:

:%!cat -s
coanor
quelle
2
Vielleicht möchten Sie ein paar Details dazu hinzufügen, wie dies funktioniert, auch wenn es sich nur um ein Zitat von der manSeite handelt.
Jasonwryan
Funktionierte nicht unter Windows 7
user674669
0

Perl benutzen:

perl -00 -pe ''

-00 Die Befehlszeilenoption aktiviert den Slurp-Modus für Absätze, was bedeutet, dass Perl Text Absatz für Absatz und nicht Zeile für Zeile liest.

Majid Azimi
quelle
0

Mit 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
PJ_Finnegan
quelle
-2

Ich weiß, dass dies alberner Code ist, aber ich wollte dieses Problem in weniger als 10 Minuten lösen, und es hat funktioniert

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done
Mahmoud Zalt
quelle
1
uniqEntfernt benachbarte gleiche Linien. Welches ist nicht das, was OP will.
Pacholik
@pacholik sagte er deutlich "Ersetzen mehrerer Leerzeilen durch eine einzelne Leerzeile" NICHT entfernen benachbarte gleiche Zeilen !!!
Mahmoud Zalt
3
Ja, genau ...
Pacholik