web-dev-qa-db-fra.com

Comment remplacer un personnage par une nouvelle 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’une nouvelle ligne. Le fichier n'est pas en mode DOS ou quoi que ce soit.

Que devrais-je faire?

Si vous êtes curieux, comme moi, vérifiez la question Pourquoi est-il une nouvelle ligne pour Vim? également.

1818
Vinko Vrsalovic

Utilisez \r au lieu de \n.

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

\n correspond à une fin de ligne (nouvelle ligne), tandis que \r correspond à un retour à la ligne. Par contre, dans les substitutions \n insère un caractère nul alors que \r insère une nouvelle ligne (plus précisément, elle est traitée comme une entrée). <CR>). Voici un petit exemple non interactif pour illustrer cela, à l'aide de 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 vidage hexadécimal 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.

2375
Konrad Rudolph

Voici le truc:

Commencez par configurer votre session vi (m) pour autoriser la correspondance de motifs avec des caractères spéciaux (par exemple: nouvelle ligne). Il vaut probablement la peine de mettre cette ligne dans votre fichier .vimrc ou .exrc.

:set magic

Ensuite, faites:

:s/,/,^M/g

Pour obtenir le caractère ^M, tapez Control-v et frapper Enter. Sous Windows, faites Control-qEnter. La seule façon dont je puisse me souvenir de cela est de rappeler le peu de sens qu’ils ont:

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

B: soit q (parce que cela signifie généralement "Quitter") ou v parce qu'il serait si facile de taper Control-c par erreur et tuer l'éditeur.

A: Faites-le ainsi.

190
Logan

Dans la syntaxe, s/foo/bar\r et \n ont des significations différentes, en fonction du 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.

plus long: (avec numéros ascii)

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

Voici une liste des caractères de contrôle ASCII , insérez-les dans vim via CTRLvCTRL---key---.
Dans bash ou les autres shells unix/linux il suffit de taper CTRL---key---. Essayer CTRLM en bash, c'est la même chose que frapper ENTER, car le shell réalise ce qu’il veut dire, même si les systèmes Linux utilisent des sauts de ligne pour la délimitation de lignes.

Pour insérer des littéraux dans bash, en les préfixant avec CTRLv travaillera également.

Essayez en bash:

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

Ceci utilise séquences d'échappement ANSI , insère les deux ^[ via CTRLvESC.

Vous pourriez aussi essayer CTRLvCTRLmENTERqui vous donnera ceci:

bash: $'\r': command not found

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

Cette caractères de contrôle ASCII est différente d’un complet tableau de symboles ASCII en ce que les caractères de contrôle, qui sont insérés dans une console/pseudoterminal/vim via le CTRL clé (haha), peut être trouvé là. Tandis qu'en C et dans la plupart des autres langues, vous utilisez habituellement les codes octaux pour représenter ces "caractères".

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


TL; DR

Habituellement, foo = \n et bar = \r.

89
sjas

Vous devez utiliser

:%s/,/^M/g

Pour obtenir le caractère ^M, appuyez sur Ctrlv suivi par Enter

50
dogbane

\r peut faire le travail ici pour vous.

34
Lasar

Avec Vim sous Windows Ctrl+Q au lieu de Ctrl+V

22
grantc

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

Donc, reformuler:

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

En effet, vim a utilisé \n dans un remplacement pour désigner le caractère NIL (ascii 0x00). Vous auriez pu vous attendre à ce que NIL ait été \0 à la place, libérant ainsi \n pour son utilisation habituelle pour le saut de ligne, mais \0 a déjà une signification dans le remplacement de regex et l'a donc déplacé vers \n. Par conséquent, il faut donc aller plus loin et déplacer également la nouvelle ligne de \n à \r (qui, dans un motif d'expression régulière, correspond au caractère de retour à la ligne, ascii 0x0d).

 caractère | code ascii | Représentation C | match de regex | remplacement de regex 
 ------------------------- + ------------ + ---- -------------- + ------------- + --------------------- --- 
 nil | 0x00 |\0 |\0 |\n 
 saut de ligne (nouvelle ligne unix) | 0x0a |\n |\n |\r 
 retour chariot | 0x0d |\r |\r | <inconnu> 

NB: ^M (Ctrl-V Ctrl-M sous Linux) insère une nouvelle ligne utilisée dans le remplacement d'une expression régulière plutôt que dans un retour à la ligne comme d'autres l'ont conseillé (je viens de l'essayer).

Notez également que vim traduira le caractère de saut de ligne lorsqu’il enregistrera dans un fichier en fonction de ses paramètres de format de fichier, ce qui risque de compliquer les choses.

10
codeshot

A partir d’Eclipse, les caractères ^M peuvent être incorporés dans une ligne et vous souhaitez les convertir en nouvelles lignes.

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

Mais si on doit substituer alors ce qui suit fonctionne

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

ci-dessus, 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 comme suit:

line1
line2
line3

est changé en

line1
|-
line2
|-
line3
7
Kiran K Telukunta

Si vous avez besoin de faire pour un fichier entier, il m'a également été suggéré d'essayer à partir de la ligne de commande.

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

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

---- citant 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 dont je ne me souviens plus et que je dois ensuite lever les yeux.

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

:% s/look_for/replace_with ^ M/g la commande ci-dessus remplacera toutes les occurrences de "look_for" par "replace_with\n" (avec\n, qui signifie 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 “entrée”.


4
user407749