Joindre des lignes entre un certain modèle de texte dans Vim

8

J'ai un fichier texte qui ressemble à ceci:

A.
text
text
text


A.
more text

more text

A.
more text

Je veux joindre toutes les lignes entre les "marqueurs" A.pour que ça ressemble à:

A.texttexttext
A.more textmore text
A.more text

Comment puis-je faire cela dans Vim?

vim noob
la source

Réponses:

4
:%s/\n\(\(A\.$\)\@!.*\)/\1/

Remplacez un motif correspondant:

  1. nouvelle ligne,
  2. un groupe contenant de

    1. pas la chaîne A.directement suivie de fin de ligne, puis
    2. n'importe quel caractère jusqu'à la fin de la ligne

avec:

  • tout correspondait sauf la nouvelle ligne de départ (c'est-à-dire le groupe ci-dessus),

et le faire à l'échelle mondiale.

Daniel Andersson
la source
1
Merci. Je n'ai aucune idée du fonctionnement de cette chose, mais il semble! Je vais devoir le disséquer soigneusement. J'ai également trouvé un moyen de contourner ce problème en joignant toutes les lignes, puis en insérant une nouvelle ligne sur "A."
vim noob
@vimnoob: Voir :help \@!dans Vim pour plus d'informations sur cette partie. Sinon, c'est simple, j'espère, avec mon explication. Un problème avec votre approche est que si " A." apparaît dans le texte, mais pas comme une ligne de marqueur isolée, il sera divisé comme s'il s'agissait à l'origine d'un marqueur. En pratique, ce n'est peut-être pas un problème (je ne sais pas à quoi ressemble votre "vrai" fichier), mais génériquement il peut provoquer un comportement indésirable si l'on n'est pas au courant de cela.
Daniel Andersson
@vimnoob: J'ai relu ma réponse, et au cas où vous n'êtes pas familier avec la :%s///syntaxe: c'est une syntaxe "rechercher et remplacer" dans Vim. :démarre la commande, %spécifie l'ensemble du tampon comme plage, sdémarre une substitution. /est le délimiteur de modèle (tout autre caractère peut être utilisé, mais /est "standard"). Le premier /démarre le modèle de recherche, le second le modèle de remplacement et le troisième le termine. Des modificateurs de fin sont disponibles pour spécifier l'insensibilité à la casse, etc. \1représentent le groupe saisi dans le modèle de recherche. :%s/foo/bar/remplace foopar bardans le fichier.
Daniel Andersson
Merci beaucoup pour votre aide. J'ai juste besoin de rechercher ceci \ @! partie que je connais la recherche de base remplacer et regexp de base.
vim noob
1
@Reman: La façon la plus simple à laquelle je pense immédiatement est d'exécuter une correspondance de modèle global ultérieure comme :%s/^A\.//. La méthode dans la réponse ne capture pas les ^A\.motifs eux-mêmes (plutôt leur absence), elle ne peut donc pas modifier ces chaînes de manière évidente.
Daniel Andersson
7

Cela fonctionne également (lorsque la première ligne commence par A.)

:v/^A/-1j!
Miro
la source
Ça marche! Agréable. +1
ZaSter
Oui, en vérité, et deux trucs nouveaux pour moi, après le match anti-pattern global (v): le 'j' pour join, et le '!' pour rejoindre sans ajouter d'espace. Je vous remercie.
fortboise
@Miro wow! je vous salue monsieur. si vous pouviez expliquer pourquoi cela fonctionne, alors super! .. aussi j'ai dû concaténer les lignes avec un caractère de tabulation entre les deux ... donc ce que j'ai fait était d'ajouter comme / $ / \ t / g un caractère de tabulation à la fin de chaque ligne avant d'émettre dessus de la commande .. une meilleure façon
ihightower