Cómo reemplazar un personaje por una nueva línea en Vim

Estoy tratando de reemplazar cada uno , 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é \ una nueva línea para Vim? .

preguntado el 16 de septiembre de 08 a las 09:09

Stack Overflow es un sitio para preguntas de programación y desarrollo. Esta pregunta parece estar fuera de tema porque no se trata de programación o desarrollo. Ver ¿Qué temas puedo preguntar aquí? en el Centro de ayuda. Quizás super User or Stack Exchange de Unix y Linux sería un mejor lugar para preguntar. -

@jww esta pregunta tiene 10 años ... parece ser demasiado viejo para migrar. Hay muchas preguntas como esta, por ejemplo: stackoverflow.com/questions/10175812/… -

@jww vim es una herramienta de uso común para programadores, y las preguntas sobre herramientas de uso común para programadores se tratan en desbordamiento de pila. Aunque obviamente esto es más adecuado en Vi y Vim. -

11 Respuestas

Utilice la herramienta \r en lugar de \n.

Sustituyendo por \n inserta un carácter nulo en el texto. Para obtener una nueva línea, use \r. Cuando el búsqueda para una nueva línea, todavía usarías \n, sin emabargo. 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 una nueva línea (más precisamente, se trata como la entrada CR). Aquí hay un pequeño ejemplo no interactivo para ilustrar esto, usando la función de línea de comando de Vim (en otras palabras, puede copiar y pegar lo siguiente en una 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.

Respondido 31 ago 20, 14:08

/ r se trata como si se presionara la tecla Enter / Return. Funciona en todas las plataformas. - luka marinko

Ojalá esto funcionara para vi clásico. En AIX v6.1, \r no funciona así. Pero puedes presionar Ctrl-V Enter en lugar de escribir \r, y funciona. - eksortso

Llego tarde a la fiesta. Si \r insertos <CR> y \n inserta un nulo, ¿cómo reemplazaría algo con un retorno de carro? - Sr. Llama

@SunnyRaj ¿estás seguro de la historia de CR y LF? Tenía la impresión de que originalmente LF movió el papel una fila hacia adelante pero no movió el cabezal de impresión, y CR movió el cabezal de impresión pero no movió el papel. Como resultado, si su sistema operativo no convirtió la entrada antes de imprimir, no podría usar solo LF o CR para obtener la salida correcta. MS DOS usó datos sin procesar de la impresora como formato de archivo de texto, Mac OS usó CR y convirtió de eso al formato sin procesar de la impresora y UNIX usó LF y lo convirtió al formato sin procesar de la impresora. - Mikko Rantalainen

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 lo siguiente:

:s/,/,^M/g

Para obtener el ^M tipo de caracter Ctrl + V y golpear Enviar. En Windows, haz Ctrl + Q, Enviar. La única forma en que puedo recordarlos es recordando el poco sentido que tienen:

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

B: Ambos q (porque normalmente significa "Salir") o v porque sería muy fácil escribir Ctrl + C por error y mata al editor.

A: Hazlo de esa manera.

Respondido el 20 de junio de 20 a las 10:06

Estoy usando GVim en Windows y no necesito el :set magic (tampoco está en mi ~ / _vimrc) o ctrl-q. Solo un simple ctrl-v seguido de enter crea el ^M carácter para mí muy bien. - Chris Phillips

Cv no representa una nueva línea; es el comando "escapar del siguiente carácter literal". No sé para qué Cv es un mnemónico, pero hay una razón por la que no se asigna mentalmente a la nueva línea. - Jim Stewart

Ctrl-v es un mnemónico para "textual", es decir, escapa la siguiente tecla presionada a su código de tecla / carácter "textual". En Windows es pegar: para mantener las cosas familiares. Ctrl-Q es para "(des) cotizar" tal vez. Bastante estúpido, de todos modos, pero puede usarlo en archivos binarios, por ejemplo, para buscar Ctrl-A a Ctrl-Z (Ascii 1-26, supongo). - tomasz gandor

Ctrl-C en realidad no mata al editor, aunque puede cancelarlo de nuevo al modo Normal. Ctrl-V significa palabra por palabra, y Ctrl-Q significa que alguien cometió el error de cargar el $VIMRUNTIME/mswin.vim archivo de configuración. No necesitas mswin. Simplemente use su propio vimrc en su lugar. - 00dani

Wow esto es increíble. yo antes hacia sed -n l hasta ahora. Es bueno saber que se puede lograr lo mismo con Ctrl-v en vim. - arquetipo

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


Corto:

Si foo:

\r == "retorno de carro" (CR / ^M)
\n == coincide con "línea de alimentación" (LF) en Linux / Mac, y CRLF en Windows

Si bar:

\r == produce LF en Linux / Mac, CRLF en Windows
\n == "byte nulo" (NUL / ^@)

Al editar archivos en Linux (es decir, en un servidor web) que se crearon inicialmente en un entorno de Windows y se cargaron (es decir, FTP / SFTP), todos los ^Mque ves en vim, son los CRes lo que Linux no traduce, ya que solo usa LFes para representar un salto de línea.


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

NUL == 0x00 == 0 == Ctrl + @ == ^@ mostrado en vim
LF == 0x0A == 10 == Ctrl + J
CR == 0x0D == 13 == Ctrl + M == ^M mostrado en vim

Aquí hay una lista de Caracteres de control ASCII. Insértelos en Vim a través de Ctrl + V,Ctrl + ---clave---.

En Bash u otros shells de Unix / Linux, simplemente escriba Ctrl + ---clave---.

Intente Ctrl + M en Bash. Es lo mismo que golpear Enviar, ya que el shell se da cuenta de lo que se quiere decir, aunque los sistemas Linux utilizan saltos de línea para delimitar líneas.

Para insertar literales en bash, anteponiéndolos con Ctrl + V también funcionará.

Prueba en Bash:

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

Esto usa Secuencias de escape ANSI. Inserta los dos ^[es a través de Ctrl + V, Esc.

También podrías intentar Ctrl + V,Ctrl + M, Enviar, que te dará esto:

bash: $'\r': command not found

Recuerda poner \r ¿desde arriba? :>

Este hermoso tono marrón de medio tono ayuda a definir y delinear tus labios en pigmentos que favorecen a todo tipo de piel, ayudándote a lograr unos labios más llenos que no se desvanecen durante horas. Caracteres de control ASCII la lista es diferente de una completa Tabla de símbolos ASCII, en que los caracteres de control, que se insertan en una consola / pseudoterminal / Vim a través del Ctrl clave (jaja), se puede encontrar allí.

Mientras que en C y en la mayoría de los demás lenguajes, normalmente se utilizan códigos octales para representar estos 'caracteres'.

Si realmente quieres saber de dónde viene todo esto: El TTY desmitificado. Este es el mejor enlace que encontrará sobre este tema, pero tenga cuidado: hay dragones.


TL; DR

Generalmente foo = \n y bar = \r.

Respondido 31 Jul 20, 09:07

Así que me intriga cómo sustituirías un personaje con un retorno de carro. código de tiro

@codeshot :s/x/^M/g debería hacer. Inserte el ^M vía ctrl-v seguido por ctrl-m. - sjas

Gracias sjas, sabes que esta pregunta es una de las más extrañas de todos los tiempos. 1008 votos a favor de la respuesta que básicamente dice nada más que "vim hace lo que encontraste. Eso es porque vim hace lo que encontraste. Nunca olvides que vim hace lo que encontraste". Esperaba encontrar una lista corta de códigos para personajes interesantes en el patrón, el reemplazo y la razón de la rareza para que sea fácil de recordar y predecir otras rarezas similares. Eso habría obtenido mi voto. - código de tiro

@codeshot una lista de caracteres de control ascii puede ayudarte. Ver cs.tut.fi/~jkorpela/chars/c0.html para mayor referencia. Actualizaré mi respuesta para incluir dos enlaces. - sjas

Necesitas usar:

:%s/,/^M/g

Para obtener el ^M personaje, prensa Ctrl + v seguido por Enviar.

respondido 15 nov., 19:09

tengo que hacer para obtener el carácter ^ M. - Jezén Thomas

\r puede hacer el trabajo aquí por usted.

Respondido 30 Abr '15, 16:04

Con Vim en Windows, use Ctrl + Q en lugar de Ctrl + V.

respondido 15 nov., 19:09

Esta es la mejor respuesta para mi forma de pensar, pero hubiera sido mejor en una tabla:

¿Por qué \ una nueva línea para Vim?

Entonces, reformulando:

Tienes que usar \r utilizar un salto de línea (ASCII 0x0A, la nueva línea de Unix) en un reemplazo de expresiones regulares, pero eso es peculiar del reemplazo: normalmente debe continuar esperando usar \n para avance de línea y \r para retorno de carro.

Esto se debe a que Vim usó \n en un reemplazo para significar el carácter NIL (ASCII 0x00). Es posible que haya esperado que NIL haya sido \0 en cambio, liberando \n para su uso habitual para el avance 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).

Carácter | Código ASCII | Representación C | Coincidencia de expresiones regulares | Reemplazo de expresiones regulares ------------------------- + ------------ + --------- --------- + ------------- + ------------------------ nada | 0x00 | \ 0 | \ 0 | \ n salto de línea (nueva línea de Unix) | 0x0a | \ n | \ n | \ r retorno de carro | 0x0d | \ r | \ r |

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 (lo acabo de probar).

También tenga en cuenta que Vim traducirá el carácter de salto de línea cuando lo guarde en un archivo en función de su configuración de formato de archivo y eso podría confundir las cosas.

respondido 15 nov., 19:10

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

:s/\r/\r/g

respondido 15 nov., 19:09

Pero si hay que sustituirlo, entonces funciona lo siguiente:

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

En lo anterior, cada línea siguiente se sustituye por la siguiente línea, y luego |- y nuevamente una nueva línea. Esto se usa en tablas wiki.

Si el texto es el siguiente:

line1
line2
line3

Se cambia a

line1
|-
line2
|-
line3

respondido 15 nov., 19:10

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

---- citando Use el editor vi para insertar un carácter de nueva línea en reemplazo


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 reemplazar, 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" (donde \ n significa nueva línea).

Para obtener la "^ M", ingrese la combinación de teclas Ctrl + V, y luego (suelte todas las teclas) presione el Enviar clave.


respondido 15 nov., 19:10

Si necesita hacerlo para un archivo completo, también se me sugirió que podría intentarlo desde la línea de comando:

sed 's/\\n/\n/g' file > newfile

respondido 15 nov., 19:10

Tenga en cuenta que esto requiere GNU sed. Intentar printf 'foo\\nbar\n' | sed 's/\\n/\n/g' para ver si funcionará en su sistema. (Gracias a la buena gente de #bash en freenode por esta sugerencia). Evan Donovan

Sí, pero la pregunta era sobre Vim. Hay una pregunta de desbordamiento de pila ¿Cómo puedo reemplazar una nueva línea (\ n) usando sed?. - Pedro Mortensen

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.