J'ai une liste de fichiers:
./a.temp.txt ./a.temp.txt
./a/b.temp.txt ./a/b.temp.txt
./a/b/c.temp.txt ./a/b/c.temp.txt
Et je veux supprimer le temp.
sur chaque ligne, mais seulement la deuxième occurrence , ainsi, le fichier devrait ressembler à:
./a.temp.txt ./a.txt
./a/b.temp.txt ./a/b.txt
./a/b/c.temp.txt ./a/b/c.txt
Comment dois-je procéder?
Réponses:
En général, vous pouvez faire correspondre la Nième occurrence de quelque chose en utilisant
\zs
et\{N}
. Il y a un exemple donné à:help \zs
.Dans votre cas, la commande serait:
la source
%s/\v(.{-}\zstemp.){2}//
C'est beaucoup plus facile à faire avec
sed
:Avec Vim, vous avez besoin d'une correspondance non gourmande, et il n'est pas facile d'étendre la méthode pour remplacer la 3ème, 4ème, etc. occurrence de
temp
. Mais cela peut être fait si vous insistez:la source
sed
applique successivement des scripts à chaque ligne d'entrée.sed
tout comme vous pouvez les diriger vers n'importe quel autre programme. Fi::%!sed 's/\.temp\././2'
.sed
sous UNIX, il lit les entréesstdin
et écrit les résultats dansstdout
.Vous pouvez également le faire avec un aperçu.
Si vous souhaitez supprimer TOUTES les occurrences après la première, vous pouvez ajouter le
g
drapeau à la fin.\(\)\@<=
Recherche tout modèle entre\(
et\)
n'ajoutera pas le texte trouvé à la correspondance.Voir
:h \@<=
pour plus d'informations.la source
Vous pouvez utiliser une macro comme @Meshpi l'a déjà suggéré. Mais, c'est une autre façon d'accomplir la même chose.
Et puis, vous pouvez simplement le répéter jusqu'à la fin. Et, il y aura beaucoup plus de façons de faire de même.
la source
Cette solution est similaire à celle de TessellatingHeckler mais s'adapte plus facilement à n'importe quel motif à supprimer.
Voici comment ça fonctionne:
:g/temp\./
pour chaque ligne correspondant à "temp."normal
exécuter ce qui suit en mode normal2n
trouver la deuxième occurrence du motifgn
sélectionnez-led
et supprimez-le.Cela fonctionnera pour n'importe quel modèle donné
:g
.normal
peut être abrégé ennorm
.gnd
est équivalent àdgn
. Edit: En fait,2ngnd
c'est équivalent àd2gn
.Voir le Wiki Vim Tips pour plus d'exemples de la commande globale.
la source
Dans Vim, vous pouvez définir la colonne avant / à / après laquelle vous souhaitez que votre correspondance se produise avec
:help \%c
:Cela supprimera tous les éléments
.temp
trouvés après la colonne 17 de chaque ligne du tampon actuel.Remarque 1: le
/g
n'est pas nécessaire avec votre échantillon.Note 2: J'utilise très souvent cette fonctionnalité pratique avec qmv . Conseillé!
la source
vidir
etvipe
du paquet moreutils .C'est en fait assez simple. Pour faire correspondre le deuxième temp, autorisez tout ce qui est suivi de "temp" suivi de quoi que ce soit, puis recherchez à nouveau temp.
Le
\zs
moyen "Commencer la sélection ici" pour que la première partie du match (tout avant le deuxième temp) ne soit pas supprimée. C'est en fait une fonctionnalité extrêmement utile que je viens d'apprendre! Sans cela, l'expression régulière devrait ressembler à ceci:la source
temp
sur une ligne, votre recette supprime la dernière, plutôt que la seconde. Blâmez la cupidité. :)My case was to match old filename to new filename, so only 2 occurrences will be on each line. And only the second one should change
.Au lieu de regex, j'irais avec une commande qui fait:
temp
et exécutez-le sur chaque ligne:
NB.
^[
est spécial et représente une pression sur la touche Échap; vous le tapez avec:Ctrl-q <Esc>
Mais une option regex, qui, je pense, n'a pas encore été suggérée, consiste à faire correspondre
temp.
suivi de quoi que ce soit, sauf un.
, ancré à la fin de la ligne.Qui correspondra
temp.txt
à la fin d'une ligne et la remplacera par juste letxt
bit.la source
J'écrirais une macro avec le curseur commençant en haut à gauche.
qq4f.dfpq
Ensuite, je sélectionnerais le reste des lignes en utilisant
V
et exécuter la macro sur ces lignes avec:'<,'>norm!@q
Cela ne fonctionnera que si le format de texte reste le même par rapport au nombre de points avant le deuxième temp.
la source
n
au lieu de4f.
parce que si un nom de fichier a plus de points, votre macro pourrait échouer ou supprimer des éléments qui ne devraient pas être supprimés.Rien ne vous empêche d'utiliser deux expressions régulières au lieu d'une seule, c'est-à-dire changer la première occurrence puis échanger les colonnes:
Ce n'est peut-être pas très intelligent, mais je le trouve très lisible.
la source
Ma tentative
la source