Sostituzione di più righe vuote con un'unica riga vuota in vim / sed


42

La domanda più o meno dice tutto. Sono consapevole che /^$/drimuoverà tutte le righe vuote, ma non riesco a vedere come dire "sostituisci due o più righe vuote con una singola riga vuota"

Qualche idea?

Risposte:


48

Se non stai sparando vim o sed per qualche altro uso, cat ha in realtà un modo semplice per comprimere più righe vuote, basta usare cat -s.

Se eri già in vim e volessi rimanere lì, potresti farlo con la ricerca interna e sostituirlo emettendo: :%s!\n\n\n\+!^M^M!g(La ^ M è la rappresentazione visiva di una nuova riga, puoi accedervi premendo Ctrl+ vEnter), o salvando te stesso il digitando semplicemente sborsare al gatto: :%!cat -s.


wow, non conoscevo l' -sopzione di cat - solo una nota storica, non è in POSIX, ma sembra essere disponibile in BSD e GNU cat.
maxschlepzig

2
Contrassegnare come "vincente" per il :%!cat -s. Scopri qualcosa di nuovo ogni giorno!
Andrew Bolster,

3
Penso che puoi anche usare \ r invece di ^ M in questo modo:%s!\n\n\n\+!\r\r!g
Niko Bellic,

Ne avevo bisogno oggi. Grazie Caleb! :)
Dɑvïd l'

19

Utilizzare \nper indicare una nuova riga nel modello di ricerca. Usa Ctrl+ Mnel testo sostitutivo o un riferimento indietro. Vedi :help patterne :help sub-replace-special(collegato da :help :s).

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

Puoi spiegare come funziona il modello di ricerca?
Sagar Jain,

@sjmp Requisito: sostituire due o più righe vuote con una singola riga vuota. Implementazione: sostituire tre o più newline consecutive con solo due newline. Vedi il manuale per una spiegazione dei costrutti usati nel comando.
Gilles 'SO- smetti di essere malvagio' il

Ma perché è necessario utilizzare un gruppo quando i suoi contenuti sono fissi?
Sabuncu,

@Sabuncu Non è necessario utilizzare un gruppo. Ma perché non usare un gruppo? Qui, ho usato un gruppo perché non è possibile copiare e incollare un comando con una nuova riga nel testo sostitutivo: è necessario inserire un carattere letterale Ctrl + M, \nnon funziona nel testo sostitutivo.
Gilles 'SO- smetti di essere malvagio' il

Ora capisco, grazie per aver dedicato del tempo per rispondere.
Sabuncu,

6

Se in Vim, basta fare questo:

:%!cat -s

2
Potresti voler aggiungere un piccolo dettaglio su come funziona, anche se è solo una citazione dalla manpagina.
Jasonwryan,

Non ha funzionato su Windows 7
user674669

0

Utilizzando Perl:

perl -00 -pe ''

-00 l'opzione della riga di comando attiva la modalità slurp del paragrafo, il che significa che Perl legge il testo paragrafo per paragrafo anziché riga per riga.


0

Con 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

So che questo è un codice sciocco, ma volevo risolvere questo problema in meno di 10 minuti e ha funzionato

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

1
uniqrimuove le linee uguali adiacenti. Che non è quello che vuole OP.
Pacholik,

@pacholik ha detto chiaramente "Sostituzione di più righe vuote con una singola riga vuota" NON rimuovere le linee uguali adiacenti !!!
Mahmoud Zalt,

3
Sì, esattamente ...
pacholik
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.