2010-06-13 7 views
27

Nell'articolo, Vim Regular Expressions, Oleg Raisky ha pronunciato la seguente comando per ridurre le molteplici righe vuote ad un unico vuoto:

:g/^$/,/./-j 

Qualcuno può descrivere come funziona?

Conosco il comando :g e le espressioni regolari. Ma non ho capito cosa fa la parte /,/./-j.

risposta

49

È davvero geniale. Scopriamolo. Il ex comando

g/^$/xyzzy 

cercherà per tutte le righe vuote ed eseguire il comando xyzzy (a ex comando arbitrario) su ciascuno di essi.

La parte difficile è che il comando xyzzy nel tuo caso è ancora un altro comando sostituto:

,/./-j 

Il ,/./- specifica un intervallo. Questo è nella forma <start>,<end> e, poiché non c'è nulla prima della virgola, assume che la linea corrente (quella in cui hai trovato la riga vuota) sia l'inizio.

Dopo la virgola è /./- che significa ricerca del carattere successivo (.: qualsiasi carattere) poi di nuovo su di una riga (/./- è l'abbreviazione di /./-1 dato che quello è implicito se non viene dato alcun valore). Troverai quel modello . sulla prima riga non vuota successiva a quella su cui stai operando.

In altre parole, la fine dell'intervallo è l'ultima riga vuota dopo o quella su cui si sta attualmente operando.

Quindi si esegue un join su tale intervallo.

Se l'inizio e la fine dell'intervallo erano uguali (solo una riga vuota era nella sezione), join non fa nulla. Se non sono uguali, join si unirà a loro.

Questo è il modo in cui combina più righe vuote in una sola.

Vediamo un esempio (numeri di riga non sono nel file):

1 Line 1 
2 
3 Line 3 
4 Line 4 
5 
6 
7 
8 
9 Line 9 

Il comando :g troverà tutte le righe vuote ed eseguire il suo funzionamento su di loro (linee 2, 5, 6, 7 e 8).

Per la linea 2, ,/./-j verrà impostato un intervallo da 2 a 2 (successivo . trovato sulla riga 3 quindi sottrarre 1). Un join sulla gamma 2,2 non fa nulla.

Per la riga 5, ,/./-j imposta un intervallo da 5 a 8 (successivo . trovato sulla riga 9 quindi sottrarre 1). Un join sulla gamma 5,8 unirà tutte quelle linee insieme.

Io non sono interamente su, ma penso che l'operazione non possa essere eseguita su righe che scompaiono come parte di un'operazione precedente. Questo perché non avrebbe senso elaborare righe cancellate in precedenza nel ciclo.

In altre parole, poiché le righe da 6 a 8 vengono cancellate (combinate con la riga 5), ​​il comando globale non funziona su di esse dopo questo. Non baso su nulla di più del fatto che la documentazione di Vim indica un algoritmo a due passaggi, uno per contrassegnare le linee, uno per eseguire l'operazione.

I potrebbe non funzionare su questo punto (non sarebbe la prima volta) ma è un dettaglio di implementazione che non influisce sulla funzionalità.

+0

Grazie. Questo è stato molto chiarificatore. Non sapevo che "comando XYZ" parte di: g potrebbe specificare un intervallo. –

+0

Il comando XYZ può essere qualsiasi comando 'ex', incluso un altro sostituto. Immagino che potresti metterne un po 'di più insieme se volessi un test _crazier_ anche della conoscenza delle immagini :-) – paxdiablo

+0

È fantastico! Stavo cercando di capire come unire più comandi ex proprio l'altro giorno .. grazie. – sml