Vim - Aggiunta di una riga vuota tra le righe


15

Come inserisco una riga vuota tra ogni riga non vuota?

per esempio. a partire dal

line 1
line 2
line 3

line 4
line 5

per

line 1

line 2

line 3

line 4

line 5

Risposte:


27

Il comando: g di Vim è progettato esattamente per questo tipo di attività; eseguendo una singola azione su ogni riga che corrisponde a un modello particolare. Ecco la mia risposta:

:g/.\n\n\@!/norm o

Lo schema che uso è /.\n\n\@!/. Suddividendolo nei suoi componenti:

  • .Corrisponde a qualsiasi personaggio della linea. (usato per scartare immediatamente qualsiasi riga vuota esistente dalla considerazione)
  • \n Corrisponde a un singolo \ n alla fine del carattere sopra
  • \n\@! Non riesce la corrispondenza se ne esiste un'altra \ n immediatamente dopo la precedente \ n.

(Cerca :h E59ulteriori informazioni \@!e identificatori di corrispondenza simili nelle espressioni regolari - ce ne sono anche un paio!)

Quindi il regex del comando: g ora ha selezionato ogni riga non vuota che è terminata da una singola nuova riga e che non è seguita da una riga vuota.

Dopo il modello in :gun'istruzione arriva il comando per l'esecuzione su linee corrispondenti. In questo caso, gli ho detto di eseguire un comando in modalità normale (abbreviato in norm) e il comando da eseguire è semplicemente o, che inserisce una riga vuota sotto la riga corrente.

Presi insieme, il comando trova ogni riga che non ha una linea vuota al di sotto di essa e ne aggiunge una. E questo è tutto quello che c'è da fare! Potresti controllare l' articolo Power of G del wiki di Vim per cose più fantasiose che puoi fare :g(ed è una sorella negativa :v) - è uno di quei comandi incredibilmente utili su cui presto farai affidamento, e poi perderai terribilmente negli editor che non ce l'hanno.


1
Precisamente. Di solito cerco scorciatoie come, :%norm oma risulta che questo non funziona come previsto nel caso di o. +1
vedi

Digita :%s/$/, quindi premi ^V, quindi premi Enter.
jpaugh

1
@jpaugh Supponendo che intendi :%s/$/<C-V><CR><CR>(per usare la codifica vim-folk comune dei tasti premuti), quell'approccio aggiunge semplicemente una nuova riga dopo ogni riga. Cioè, le linee che sono già separate da spazi vuoti (vedi Linea 3 -> Linea 4, nel testo di esempio) finiscono per ottenere ulteriori linee vuote. La domanda originale era quella di evitare di aggiungere ulteriori righe vuote dove già esistevano nel testo iniziale.
Trevor Powell

3

Quando ho testato la ricerca globale di @ NeilForester e ho sostituito la risposta, ho scoperto che mancava ogni secondo la sostituzione prevista in righe consecutive non vuote se le righe avevano solo un carattere in ciascuna. Ciò sembra essere dovuto al motivo che ha iniziato a corrispondere in ogni occasione dopo l'ultimo carattere che corrispondeva all'occasione precedente.

L'uso di lookbehind e lookahead risolve questo problema e rende la regex un po 'più breve:

:%s/\n\@<!\n\n\@!/\r\r/g

Grazie! Funziona e non aggiunge più righe se eseguo nuovamente la ricerca (se diciamo, ho aggiunto nuove righe al mio file).

1
Potresti spiegare cosa significa ciascuna delle regex nel modello di ricerca? Guardando vim help, \n\@<!\nsignifica che qualsiasi interruzione di riga che non è corretta dopo un'altra interruzione di linea è corretta? Ma non riuscivo a capire cosa \n\@!significhi. Mi piacerebbe capirlo in modo da poterlo imparare e applicarlo ad altri schemi di ricerca :)

Sì, \n\@<!\nindica qualsiasi interruzione di riga che non segue immediatamente un'altra interruzione di riga. \n\@!corrisponde a larghezza zero se l'atomo precedente (cioè \n) non corrisponde appena prima di quanto segue. Prova :help \@<!a vedere la documentazione su questo in vim. I
Simone,

3

Un altro modo:

%s/\(.\)\n\(.\)/\1\r\r\2/

Che significa,

\(.\) match and capture a non-newline character,
\n    match a newline
\(.\) match and capture a non-newline character

sostituisci con: prima acquisizione, doppie nuove righe e seconda acquisizione.

Ad esempio, line1\nLine2risultati in \1 = 1e \2 = L.


0

Correggimi se sbaglio. Credo che tu usi la lettera k quando sei in modalità comando per spostarti lungo una linea. Quindi accedere alla modalità di inserimento e aggiungere la riga successiva. Ripetere se necessario? Spero che sia di aiuto!


ksi sposta di una riga. jsi sposta lungo una linea.
Neil Forrester

Sì, davvero. Errore mio. Grazie Neil!

0
/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Quindi premere <F2>. Ciò cercherà due righe consecutive non vuote, quindi aggiungerà ripetutamente una linea tra di esse.

Modificare:

Ecco un modo alternativo per farlo con una singola ricerca globale e sostituire:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g

Il mio file ha molte righe. C'è un modo per eseguire una ricerca regex e inserire una riga vuota per l'intero file? Ho esaminato stackoverflow.com/questions/2673209/… ma non sono riuscito a capire cosa significano tutti i comandi regex.

Vedi la mia modifica sopra per un modo alternativo di realizzare la stessa cosa in un singolo comando e senza una mappatura ricorsiva. Il primo modo dovrebbe funzionare per l'intero file però.
Neil Forrester

0

Prova questo comando ( 16caratteri):

:%!sed G|cat -s

Invece di tentare di "vimgolf" un breve comando, una piccola spiegazione delle opzioni piuttosto oscure utilizzate sarebbe più utile.
Ingo Karkat,

0

Non so quanto sia lungo il tuo file ma uno dei metodi più semplici è digitare oin modalità comando. E nella riga successiva .. Questo potrebbe essere caricato in una macro semplice.

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.