Comment remplacer un caractère par un retour à la ligne dans Vim?

J'essaie de remplacer chaque , dans le fichier actuel par une nouvelle ligne:

:%s/,/n/g 

Mais il insère ce qui ressemble à un ^@ au lieu d'un saut de ligne réel. Le fichier n'est pas en mode DOS ou quoi que ce soit.

Que dois-je faire?

Si vous êtes curieux, comme moi, Vérifiez la question Pourquoi r est une nouvelle ligne pour Vim? ainsi.

1647
demandé sur Robert Harvey 2008-09-16 15:19:39

11 réponses

Utiliser \r au lieu de \n.

Substitution par \n insère un caractère nul dans le texte. Pour obtenir une nouvelle ligne, Utilisez \r. Lorsque recherche pour un retour à la ligne, vous utiliserez toujours \n, cependant. Cette asymétrie est due au fait que \n et \r faire des choses légèrement différentes:

\n correspond à une fin de ligne (saut de ligne), alors que \r correspond à un retour chariot. D'autre part, dans les substitutions \n insère un caractère nul alors que \r insère un newline (plus précisément, il est traité comme l'entrée ). Voici un petit exemple non interactif pour illustrer cela, en utilisant la fonction de ligne de commande Vim (en d'autres termes, vous pouvez copier et coller ce qui suit dans un terminal pour l'exécuter). xxd affiche un hexdump du fichier résultant.

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 d'autres termes, \n a inséré l'octet 0x00 dans le texte; \r a inséré l'octet 0x0a.

2134
répondu Konrad Rudolph 2015-05-11 21:01:25

Voici l'astuce:

Tout d'abord, définissez votre session vi(m) pour permettre la correspondance de motifs avec des caractères spéciaux (par exemple: newline). Il vaut probablement la peine de mettre cette ligne dans votre .vimrc ou .fichier exrc.

:set magic

Ensuite, faites:

:s/,/,^M/g

Pour obtenir le ^M caractère, de type Contrôle-v et a frappé Entrer. Sous Windows, effectuez le contrôle -q, entrez . La seule façon dont je peux me souvenir de ceux - ci est de se rappeler à quel point ils font peu de sens:

A: quel serait le pire caractère de contrôle à utiliser pour représenter une nouvelle ligne?

B: , Soit q (car il signifie généralement "Quitter") ou v, car il serait tellement facile de taper Contrôle-c, par erreur, et de tuer l'éditeur.

A: faites-le.

167
répondu Logan 2016-10-27 18:31:21

Dans la syntaxe s/foo/bar \r et \n ont des significations différentes selon le contexte.


Court:

Pour foo:
\N = nouvelle ligne (LF sous linux/mac, CRLF sous windows)
\r = retour chariot (CR)

Pour bar:
\r = est une nouvelle ligne
\ n = octet nul.

Longer: (avec des nombres ascii)

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

Voici une liste de la caractères de contrôle ASCII, insérez-les dans les vim par CTRLvCTRL---clé---.
Dans bash ou dans les autres shells unix/linux, tapez simplement CTRL---clé---. Essayez CTRLM dans bash, c'est la même chose que de frapper ENTER, car le shell réalise ce que l'on entend, même si les systèmes linux utilisent des flux de ligne pour délimiter les lignes.

À insérez littérale en bash, en les préfixant avec CTRLv fonctionnera également.

Essayez dans bash:

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

On utilise séquences d'échappement ANSI, insérez les deux ^['s via CTRLvESC.

, Vous pouvez également essayer de CTRLvCTRLmSAISISSEZ, ce qui vous donnera ceci:

bash: $'\r': command not found

Rappelez-vous le \r d'en haut? :>

Ce contrôle ASCII characters list est différent d'une table de symboles ASCII complète, en ce sens que les caractères de contrôle, qui sont insérés dans une console/pseudoterminal/vim via la touche CTRL (haha), peuvent y être trouvés. Alors qu'en C et dans la plupart des autres langues, vous utilisez généralement les codes octaux pour représenter ces "caractères".

Si vous voulez vraiment savoir où tout cela vient de: http://www.linusakesson.net/programming/tty/.
C'est le meilleur lien que vous viendrez à travers sur ce sujet, mais méfiez-vous: il y a des dragons.


TL;DR

Généralement foo = \n, et bar = \r.

70
répondu sjas 2018-09-02 19:16:36

Vous devez utiliser

:%s/,/^M/g

Pour obtenir le ^M caractère, appuyez sur Ctrl v, suivie par Entrer

45
répondu dogbane 2015-08-04 20:00:08

\r peut faire le travail pour vous.

28
répondu Lasar 2015-04-30 15:48:15

Avec Vim sur Windows utiliser Ctrl+Q au lieu de Ctrl+V

20
répondu grantc 2011-12-11 10:17:23

À partir d'eclipse, les caractères ^M peuvent être intégrés dans une ligne et vous souhaitez les convertir en sauts de ligne.

:s/\r/\r/g
8
répondu rickfoosusa 2015-04-19 20:25:12

Mais si l'on doit remplacer alors la chose suivante fonctionne

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

Dans ce qui précède, chaque ligne suivante est remplacée par la ligne suivante, puis | - et encore une ligne suivante. Ceci est utilisé dans les tables wiki. si le texte est le suivant:

line1
line2
line3

Est remplacé par

line1
|-
line2
|-
line3
5
répondu Kiran Telukunta 2012-02-07 08:09:42

C'est la meilleure réponse pour la façon dont je pense, mais il aurait été plus agréable dans un tableau: https://stackoverflow.com/a/12389839/962394.

Donc, reformulation:

Vous devez utiliser \r pour utiliser un saut de ligne (ascii 0x0a, le saut de ligne unix) dans un remplacement regex mais cela est particulier au remplacement - vous devriez normalement continuer à vous attendre à utiliser \n pour le saut de ligne et \r pour le retour chariot.

C'est parce que vim a utilisé \n dans un remplacement pour signifier le Caractère nul (ascii 0x00). Vous auriez pu vous attendre à ce que NIL ait été \0 à la place, libérant \n pour son utilisation habituelle pour le saut de ligne, mais \0 a déjà une signification dans les remplacements regex, donc il a été déplacé vers \n. Par conséquent, aller plus loin pour également déplacer la nouvelle ligne de \n à \r (qui dans un motif regex est le caractère de retour chariot, 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 sous linux) insère une nouvelle ligne lorsqu'elle est utilisée dans un remplacement de regex plutôt qu'un retour chariot comme d'autres l'ont conseillé (je viens de l'essayer).

Notez également que vim va traduire le caractère de saut de ligne lorsqu'il enregistre dans un fichier en fonction de ses paramètres de format de fichier et cela pourrait confondre les choses.

5
répondu codeshot 2017-05-23 11:47:31

Si vous devez faire pour un fichier entier, il m'a également été suggéré que vous puissiez essayer à partir de la ligne de commande

sed 's/\\n/\n/g' file > newfile
4
répondu Evan Donovan 2012-02-09 23:01:29

Voici la réponse qui a fonctionné pour moi. De ce type

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


Quelque chose d'autre que je dois faire et que je ne me souviens pas et que je dois ensuite regarder.

Dans vi pour insérer un caractère de nouvelle ligne dans une recherche et un remplacement, procédez comme suit:

:%s / look_for / replace_with^M / g la commande ci-dessus remplacerait toutes les instances de " look_for "par" replace_with\n " (Avec \n signification nouvelle ligne)

Pour obtenir le "^M", entrez la combinaison de touches "ctl-V" puis après cela (relâchez toutes les touches) appuyez sur la touche "enter".


2
répondu 2012-02-03 19:31:15