¿Cómo reemplazar un carácter por una nueva línea en Vim?


Estoy tratando de 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é debo hacer?

Si tienes curiosidad, como yo, revisa la pregunta ¿Por qué es \r una nueva línea para Vim? también.

Author: Robert Harvey, 2008-09-16

11 answers

Use \r en lugar de \n.

Sustituyendo por \n inserta un carácter nulo en el texto. Para obtener una nueva línea, utilice \r. Sin embargo, cuando busca una nueva línea, todavía usaría \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 sustituciones \n inserta un carácter nulo mientras que \r inserta un nueva línea (más precisamente, se trata como la entrada ). Aquí hay un pequeño ejemplo no interactivo para ilustrar esto, usando la función de línea de comandos de Vim (en otras palabras, puede copiar y pegar lo siguiente en un terminal para ejecutarlo). xxd muestra un hexdump 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.

 2134
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 21:01:25

Este es el truco:

Primero, configure su sesión vi(m) para permitir la coincidencia de patrones con caracteres especiales (es decir: nueva línea). Probablemente vale la pena poner esta línea en su .vimrc o .archivo exrc.

:set magic

A continuación, haga:

:s/,/,^M/g

Para obtener el ^M caracteres, escriba Control-v y pulsa Introduce. En Windows, haga Control-q, Introduzca. La única manera en que puedo recordar esto es recordando lo poco que tienen sentido:

A: ¿Cuál sería el peor carácter de control para representar una nueva línea?

B: o Bien q (porque generalmente significa "Salir") o v porque sería muy fácil escribir Control-c por error y matar al editor.

A: Hazlo así.

 167
Author: Logan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-27 18:31:21

En la sintaxis s/foo/bar \r y \n tienen diferentes significados, dependiendo del contexto.


Corto:

Para foo:
\n = nueva línea (LF en linux/mac, CRLF en windows)
\r = retorno de carro (CR)

Para bar:
\r = is newline
\n = byte nulo.

Más largo: (con números ascii)

NUL = 0x00 = 0 = CTRL@
LF = 0x0A = 10 = CTRLJ
CR = 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 - - - . Try CTRLM en bash, es lo mismo que golpear ENTER, ya que el shell se da cuenta de lo que significa, a pesar de que los sistemas linux utilizan Fuentes de línea para delimitar líneas.

A insertar literal en bash, anteponiendo con CTRLv, también trabajo.

Try in bash:

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

Este utiliza secuencias de escape ANSI, inserte los dos ^['s a través de CTRLvESC.

También puede intentar CTRLvCTRLmINTRODUZCA, el cual le dará esta:

bash: $'\r': command not found

¿Recuerdas el \r de arriba? :>

Este control ASCII characters list es diferente de una tabla de símbolos ASCII completa , en que los caracteres de control, que se insertan en una consola/pseudoterminal/vim a través de la tecla CTRL (jaja), se pueden encontrar allí. Mientras que en C y en la mayoría de los otros lenguajes usualmente se usan los códigos octales para representar estos 'caracteres'.

Si realmente quieres saber de dónde viene todo esto: http://www.linusakesson.net/programming/tty/.
Este es el mejor enlace que vendrás a través de este tema, pero cuidado: Hay dragones.


TL; DR

Normalmente foo = \n, y bar = \r.

 70
Author: sjas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-02 19:16:36

Necesitas usar

:%s/,/^M/g

Para obtener el ^M caracteres, pulse Ctrl v seguido por Introduce

 45
Author: dogbane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-04 20:00:08

\r puedo hacer el trabajo aquí para usted.

 28
Author: Lasar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-30 15:48:15

Con Vim en Windows uso Ctrl+P en lugar de Ctrl+V

 20
Author: grantc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-11 10:17:23

Desde eclipse, los caracteres ^M se pueden incrustar en una línea, y desea convertirlos en nuevas líneas.

:s/\r/\r/g
 8
Author: rickfoosusa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-19 20:25:12

Pero si uno tiene que sustituir entonces lo siguiente funciona

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

En lo anterior, cada línea siguiente se sustituye por la siguiente línea y luego |- y de nuevo una línea siguiente. Esto se usa en las tablas wiki. si el texto es el siguiente:

line1
line2
line3

Se cambia a

line1
|-
line2
|-
line3
 5
Author: Kiran Telukunta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-07 08:09:42

Esta es la mejor respuesta para la forma en que pienso, pero habría sido más agradable en una tabla: https://stackoverflow.com/a/12389839/962394 .

Así que, reformulando:

Necesita usar \r para usar una línea de alimentación (ascii 0x0a, la nueva línea de unix) en un reemplazo de expresiones regulares, pero eso es peculiar de la sustitución - normalmente debería seguir esperando usar \n para la línea de alimentación y \r para el retorno de carro.

Esto se debe a que vim usó \n en un reemplazo para significar Carácter CERO (ascii 0x00). Es posible que hubiera esperado que NIL hubiera sido \0 en su lugar, liberando \n para su uso habitual para la alimentación 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, ir más allá para cambiar también 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).

character                | ascii code | C representation | regex match | regex replacement
-------------------------+------------+------------------+-------------+------------------------
nil                      | 0x00       | \0               | \0          | \n
line feed (unix newline) | 0x0a       | \n               | \n          | \r
carriage return          | 0x0d       | \r               | \r          | <unknown>

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 han aconsejado (acabo de probarlo).

También tenga en cuenta que vim traducirá el carácter de alimentación de línea cuando se guarda en el archivo basado en su configuración de formato de archivo y que podría confundir las cosas.

 5
Author: codeshot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:31

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
 4
Author: Evan Donovan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-09 23:01:29

Aquí está la respuesta que funcionó para mí. De este tipo

----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 el "^M", ingrese la combinación de teclas "ctl-V" luego después de eso (suelte todas las teclas) presione la tecla "enter".


 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-03 19:31:15