Estoy intentando reemplazar cada ,
en el archivo actual por una nueva línea:
:%s/,/\n/g
Pero inserta lo que parece un ^@
en lugar de una nueva línea real. El archivo no está en modo DOS ni nada.
¿Qué tengo que hacer?
Si tiene curiosidad, como yo, verifique la pregunta¿Por qué es una nueva línea para Vim?también.
\r
en lugar de \n
.Al sustituir por \n
se inserta un carácter nulo en el texto. Para obtener una nueva línea, use \r
. Cuando buscando una nueva línea, aún así deberías usar \n
. Esta asimetría se debe al hecho de que \n
y \r
hacer cosas ligeramente diferentes :
\n
coincide con un final de línea (nueva línea), mientras que \r
coincide con un retorno de carro. Por otro lado, en las sustituciones \n
inserta un carácter nulo mientras que \r
inserta una nueva línea (más precisamente, se trata como la entrada <CR>). Aquí hay un pequeño ejemplo no interactivo para ilustrar esto, utilizando la función de línea de comandos Vim (en otras palabras, puede copiar y pegar lo siguiente en un terminal para ejecutarlo). xxd
muestra un volcado hexadecimal del archivo resultante.
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.
En otras palabras, \n
ha insertado el byte 0x00 en el texto; \r
ha insertado el byte 0x0a.
Aquí está el truco:
Primero, configure su sesión vi (m) para permitir la coincidencia de patrones con caracteres especiales (es decir, nueva línea). Probablemente valga la pena poner esta línea en su archivo .vimrc o .exrc.
:set magic
A continuación, haz:
:s/,/,^M/g
Para obtener el carácter ^M
, escriba Control-v y golpear Enter. Bajo Windows, haz Control-q, Enter. La única forma en que puedo recordar esto es recordando lo poco sentido que tienen:
A: ¿Cuál sería el peor carácter de control a usar para representar una nueva línea?
B: Ya sea
q
(porque generalmente significa "Salir") ov
porque sería muy fácil de escribir Control-c por error y mata al editor.A: Hazlo así
En la sintaxis, s/foo/bar
\r
y \n
tienen diferentes significados, según el contexto.
Para foo
:
\n = nueva línea (LF en linux/mac, CRLF en Windows)
\r = retorno de carro (CR)
Para bar
:
\r = es nueva línea
\n = byte nulo.
NUL
= 0x00 = 0 = CTRL@LF
= 0x0A = 10 = CTRLJCR
= 0x0D = 13 = CTRLM
Aquí hay una lista de los caracteres de control ASCII , insértelos en vim
a través de CTRLvCTRL---key---.
En bash
o en los otros shells de unix/linux simplemente escriba CTRL---key---. Tratar CTRLM en bash, es lo mismo que golpear ENTER, a medida que Shell se da cuenta de lo que se quiere decir, a pesar de que los sistemas linux usan Avances de línea para delimitar líneas.
Para insertar literales en bash, anteponiéndolos con CTRLv También funcionará.
Prueba en bash:
echo ^[[33;1mcolored.^[[0mnot colored.
Esto utiliza secuencias de escape ANSI , inserte los dos ^[
's a través de CTRLvESC.
También puedes probar CTRLvCTRLmENTER, que te dará esto:
bash: $'\r': command not found
¿Recuerdas el \r
desde arriba? :>
Esta caracteres de control ASCII lista es diferente de una --- tabla de símbolos ASCII , en que los caracteres de control, que se insertan en una consola/pseudoterminal/vim a través de CTRL clave (jaja), se puede encontrar allí. Mientras que en C y en la mayoría de los otros idiomas, usualmente usas los códigos octales para representar estos "caracteres".
Si realmente quiere saber de dónde viene todo esto: http://www.linusakesson.net/programming/tty/ .
Este es el mejor enlace que encontrará sobre este tema, pero tenga cuidado: hay dragones.
TL; DR
Normalmente foo
= \n
, y bar
= \r
.
Necesitas usar
:%s/,/^M/g
Para obtener el carácter ^M
, presione Ctrlv seguido por Enter
\r
puede hacer el trabajo aquí por ti.
Con Vim en uso de Windows Ctrl+Q en lugar de Ctrl+V
Creo que esta es la mejor respuesta, pero hubiera sido mejor en una tabla: https://stackoverflow.com/a/12389839/962394 .
Entonces, reescribiendo:
Debe usar \r
para usar un salto de línea (ascii 0x0a
, unix newline) en un reemplazo de expresiones regulares, pero eso es propio del reemplazo. Normalmente, debe continuar usando \n
para el salto de línea y \r
para el retorno de carro.
Esto se debe a que vim utilizó \n
en un reemplazo para indicar el carácter NIL (ascii 0x00
). Es posible que haya esperado que NIL haya sido \0
, liberando \n
para su uso habitual para el salto de línea, pero \0
ya tiene un significado en los reemplazos de expresiones regulares por lo que se cambió a \n
. Por lo tanto, yendo más lejos también para cambiar la nueva línea de \n
a \r
(que en un patrón de expresiones regulares es el carácter de retorno de carro, ascii 0x0d
).
personaje | código ASCII | Representacion en c | partido regex | reemplazo de expresiones regulares ------------------------- + ------------ + ---- -------------- + ------------- + --------------------- --- nil | 0x00 |\0 |\0 |\n avance de línea (nueva línea unix) | 0x0a |\n |\n |\r retorno de carro | 0x0d |\r |\r | <desconocido>
NB: ^M
(Ctrl-V Ctrl-M en linux) inserta una nueva línea cuando se usa en un reemplazo de expresiones regulares en lugar de un retorno de carro como otros lo han aconsejado (simplemente lo probé).
También tenga en cuenta que vim traducirá el carácter de avance de línea cuando se guarde en un archivo según la configuración de formato de archivo y eso podría confundir las cosas.
Desde Eclipse, los caracteres ^M
se pueden incrustar en una línea, y desea convertirlos a nuevas líneas.
:s/\r/\r/g
Pero si uno tiene que sustituirlo, entonces lo siguiente funciona.
:%s/\n/\r\|\-\r/g
en lo anterior, cada línea siguiente se sustituye con la línea siguiente y luego | - y nuevamente la línea siguiente. Esto se usa en tablas wiki. Si el texto es el siguiente:
line1
line2
line3
se cambia a
line1
|-
line2
|-
line3
Si necesita hacer para un archivo completo, también se me sugirió que podría probar desde la línea de comandos
sed 's/\\n/\n/g' file > newfile
Aquí está la respuesta que funcionó para mí. De este chico
---- citando http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/
Algo más que tengo que hacer y no puedo recordar y luego tengo que mirar hacia arriba.
En vi para insertar un carácter de nueva línea en una búsqueda y reemplazo, haga lo siguiente:
:% s/look_for/replace_with ^ M/g el comando anterior reemplazaría todas las instancias de “look_for” con “replace_with\n” (con\n significa nueva línea)
para obtener la "^ M", ingrese la combinación de teclas "ctl-V" y luego (suelte todas las teclas) presione la tecla "enter".