it-swarm.it

Come sostituire un personaggio con una nuova riga in Vim

Sto provando a sostituire ogni , nel file corrente con una nuova riga:

:%s/,/\n/g 

Ma inserisce quello che sembra un ^@ invece di una nuova riga effettiva. Il file non è in modalità DOS o altro.

Cosa dovrei fare?

Se sei curioso, come me, controlla la domanda Perché\r nuova riga per Vim? come bene.

1775
Vinko Vrsalovic

Utilizza \r anziché \n.

Sostituendo con \n si inserisce un carattere nullo nel testo. Per ottenere una nuova riga, usa \r. Quando ricerca per una nuova riga, dovresti comunque usare \n, comunque. Questa asimmetria è dovuta al fatto che \n e \rfanno cose leggermente diverse :

\n corrisponde alla fine della riga (newline), mentre \r corrisponde a un ritorno a capo. D'altra parte, nelle sostituzioni \n inserisce un carattere nullo mentre \r inserisce una nuova riga (più precisamente, viene trattato come input <CR>). Ecco un piccolo esempio non interattivo per illustrare questo, utilizzando la funzione da riga di comando di Vim (in altre parole, è possibile copiare e incollare quanto segue in un terminale per eseguirlo). xxd mostra un dump esadecimale del file risultante.

echo bar > test
(echo 'Before:'; xxd test) > output.txt
vim test '+s/b/\n/' '+s/a/\r/' +wq
(echo 'After:'; xxd test) >> output.txt
more output.txt
Before:
0000000: 6261 720a                                bar.
After:
0000000: 000a 720a                                ..r.

In altre parole, \n ha inserito il byte 0x00 nel testo; \r ha inserito il byte 0x0a.

2317
Konrad Rudolph

Ecco il trucco:

Per prima cosa, imposta la tua sessione vi (m) per consentire la corrispondenza del modello con caratteri speciali (es .: newline). Probabilmente vale la pena di inserire questa riga nel tuo file .vimrc o .exrc.

:set magic

Quindi, fai:

:s/,/,^M/g

Per ottenere il carattere ^M, digitare Control-v e colpisci Enter. Sotto Windows, fallo Control-qEnter. L'unico modo in cui posso ricordare questi è ricordando quanto poco senso abbiano:

A: Quale sarebbe il peggior personaggio di controllo da utilizzare per rappresentare una nuova riga?

B: O q(perché in genere significa "Esci") o vperché sarebbe così facile da digitare Control-c per errore e uccidi l'editor.

A: Fallo così.

184
Logan

Nella sintassi s/foo/bar\r e \n hanno significati diversi, a seconda del contesto.


corto:

Per foo:
\n = newline (LF su linux/mac, CRLF su Windows)
\r = ritorno a capo (CR)

Per bar:
\r = è newline
\n = byte null.

più a lungo: (con numeri ascii)

NUL = 0x00 = 0 = CTRL@
LF = 0x0A = 10 = CTRLJ
CR = 0x0D = 13 = CTRLM

Ecco una lista di caratteri di controllo ASCII , inserirli in vim via CTRLvCTRL---key---.
In bash o le altre shell unix/linux digitano semplicemente CTRL---key---. Provare CTRLM in bash, è come colpire ENTER, poiché la Shell si rende conto di cosa si intende, anche se i sistemi linux utilizzano i Feed di riga per delimitare la linea.

Per inserire letterali in bash, anteponendoli con CTRLv funzionerà anche.

Prova in bash:

echo ^[[33;1mcolored.^[[0mnot colored.

Questo usa ANSI escape sequences , inserisci i due ^[ 's via CTRLvESC.

Potresti anche provare CTRLvCTRLmENTER, che ti darà questo:

bash: $'\r': command not found

Ricorda il \r dall'alto? :>

Questo caratteri di controllo ASCII l'elenco è diverso da un completo tabella dei simboli ASCII , in quanto i caratteri di controllo, che sono inseriti in una console/pseudoterminale/vim tramite il CTRL chiave (haha), può essere trovato lì. Mentre in C e nella maggior parte delle altre lingue di solito usi i codici ottali per rappresentare questi "personaggi".

Se vuoi veramente sapere da dove viene tutto questo: http://www.linusakesson.net/programming/tty/ .
Questo è il miglior link su questo argomento, ma attenzione: ci sono i draghi.


TL; DR

Di solito foo = \n e bar = \r.

84
sjas

Devi usare

:%s/,/^M/g

Per ottenere il carattere ^M, premere Ctrlv seguito da Enter

50
dogbane

\r può fare il lavoro qui per te.

33
Lasar

Con Vim su Windows Ctrl+Q al posto di Ctrl+V

22
grantc

Questa è la migliore risposta per il mio modo di pensare, ma sarebbe stata più bella in una tabella: https://stackoverflow.com/a/12389839/962394 .

Quindi, riformulazione:

È necessario utilizzare \r per utilizzare un feed di riga (ascii 0x0a, unix newline) in una regex sostitutiva ma che è peculiare della sostituzione - normalmente si dovrebbe continuare a prevedere l'utilizzo di \n per il feed di riga e \r per il ritorno a capo.

Questo perché vim ha usato \n in una sostituzione per indicare il carattere NIL (ascii 0x00). Potresti esserti aspettato che NIL fosse \0, liberando \n per il suo uso usuale per il feed di riga, ma \0 ha già un significato nelle sostituzioni regex, quindi è stato spostato su \n. Quindi, andando oltre, sposta anche la nuova riga da \n a \r (che in un modello regolare è il carattere di ritorno a capo, ascii 0x0d).

 carattere | codice ASCII | Rappresentazione C | regex match | regex replacement 
 ------------------------- + ------------ + ---- -------------- + ------------- + --------------------- --- 
 nil | 0x00 |\0 |\0 |\n 
 avanzamento riga (unix newline) | 0x0a |\n |\n |\r 
 ritorno a capo | 0x0d |\r |\r | <Sconosciuta> 

NB: ^M (Ctrl-V Ctrl-M su linux) inserisce una newline quando viene usata in una regex replacement piuttosto che in un ritorno a capo come altri hanno consigliato (l'ho appena provato).

Si noti inoltre che vim tradurrà il carattere di avanzamento riga quando viene salvato su file in base alle impostazioni del formato file e ciò potrebbe confondere gli argomenti.

10
codeshot

Da Eclipse, i caratteri ^M possono essere incorporati in una riga e si desidera convertirli in newline.

:s/\r/\r/g
10
rickfoosusa

Ma se si deve sostituire, allora la seguente cosa funziona

:%s/\n/\r\|\-\r/g

nella riga precedente ogni riga successiva viene sostituita con la riga successiva e quindi | - e di nuovo una riga successiva. Questo è usato nelle tabelle wiki. se il testo è il seguente:

line1
line2
line3

è cambiato in

line1
|-
line2
|-
line3
7

Se hai bisogno di fare un intero file, mi è stato anche suggerito di provare dalla riga di comando

sed 's/\\n/\n/g' file > newfile
6
Evan Donovan

Ecco la risposta che ha funzionato per me. Da questo ragazzo

---- quoting http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/


Qualcos'altro che devo fare e non riesco a ricordare e poi devo cercare.

In vi per inserire un carattere di nuova riga in una ricerca e sostituisci, fai quanto segue:

:% s/look_for/replace_with ^ M/g il comando precedente sostituisce tutte le istanze di "look_for" con "replace_with\n" (con\n che significa newline)

per ottenere il "^ M", inserire la combinazione di tasti "ctl-V", quindi (rilasciare tutti i tasti) premere il tasto "invio".


4
user407749