Ich habe eine Liste von Dateien:
./a.temp.txt ./a.temp.txt
./a/b.temp.txt ./a/b.temp.txt
./a/b/c.temp.txt ./a/b/c.temp.txt
Und ich möchte das temp.
in jeder Zeile entfernen , aber nur das zweite Vorkommen , daher sollte die Datei so aussehen:
./a.temp.txt ./a.txt
./a/b.temp.txt ./a/b.txt
./a/b/c.temp.txt ./a/b/c.txt
Wie soll ich das machen?
Antworten:
Im Allgemeinen können Sie das N-te Vorkommen von etwas mit
\zs
und abgleichen\{N}
. Es gibt ein Beispiel bei:help \zs
.In Ihrem Fall wäre der Befehl:
quelle
%s/\v(.{-}\zstemp.){2}//
Dies ist viel einfacher gemacht mit
sed
:Mit Vim benötigen Sie einen nicht gierigen Abgleich, und es ist nicht einfach, die Methode auf das Ersetzen des 3., 4. usw. Vorkommens von zu erweitern
temp
. Aber es kann getan werden, wenn Sie darauf bestehen:quelle
sed
Wendet nacheinander Skripte auf jede Eingabezeile an.sed
genau wie an jedes andere Programm weiterleiten. Fi ::%!sed 's/\.temp\././2'
.sed
In UNIX-freundlich liest es Eingaben vonstdin
und schreibt Ergebnisse instdout
.Sie können dies auch mit einem Lookbehind tun.
Wenn Sie ALLE Vorkommen nach dem ersten entfernen möchten , können Sie das
g
Flag am Ende anhängen .\(\)\@<=
Sucht nach einem Muster zwischen\(
und\)
fügt den gefundenen Text jedoch nicht zur Übereinstimmung hinzu.Siehe
:h \@<=
für weitere Informationen.quelle
Sie können ein Makro verwenden, wie @Meshpi bereits vorgeschlagen hat. Dies ist jedoch eine andere Möglichkeit, dasselbe zu erreichen.
Und dann können Sie es einfach bis zum Ende wiederholen. Und es wird noch viel mehr Möglichkeiten geben, dasselbe zu tun.
quelle
Diese Lösung ähnelt der von TessellatingHeckler, lässt sich jedoch leichter an das zu löschende Muster anpassen.
So funktioniert das:
:g/temp\./
für jede Zeile, die mit "temp" übereinstimmt.normal
Führen Sie im normalen Modus Folgendes aus2n
Finden Sie das zweite Auftreten des Mustersgn
wähle es ausd
und löschen Sie es.Dies funktioniert für jedes Muster
:g
.normal
kann abgekürzt werden mitnorm
.gnd
ist äquivalent zudgn
. Bearbeiten: In der Tat2ngnd
ist gleichbedeutend mitd2gn
.Weitere Beispiele für den globalen Befehl finden Sie im Vim Tips Wiki .
quelle
In Vim können Sie die Spalte vor / um / nach definieren, mit der Ihr Abgleich erfolgen soll
:help \%c
:Dadurch werden alle
.temp
nach Spalte 17 gefundenen Zeilen jeder Zeile im aktuellen Puffer entfernt.Hinweis 1:
/g
Dies ist bei Ihrer Probe nicht erforderlich.Hinweis 2: Ich verwende diese praktische Funktion sehr oft mit qmv . Empfohlen!
quelle
vidir
undvipe
aus dem moreutils- Paket.Das ist eigentlich ziemlich einfach. Um mit der zweiten Temperatur übereinzustimmen, lassen Sie alles zu, gefolgt von "temp" gefolgt von irgendetwas, und suchen Sie dann erneut nach temp.
Das
\zs
bedeutet "Auswahl hier starten", damit der erste Teil des Spiels (alles vor dem zweiten Temp) nicht entfernt wird. Es ist tatsächlich eine äußerst nützliche Funktion, die ich gerade kennengelernt habe! Ohne sie müsste der Regex so aussehen:quelle
temp
in einer Zeile befinden, löscht Ihr Rezept das letzte und nicht das zweite. Beschuldige die Gier. :)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
.Anstelle von Regex würde ich einen Befehl verwenden, der Folgendes bewirkt:
temp
und führen Sie es in jeder Zeile aus:
NB.
^[
ist etwas Besonderes und repräsentiert das Drücken der Escape-Taste; Sie tippen es mit:Ctrl-q <Esc>
Aber eine Regex-Option, von der ich glaube, dass sie noch nicht vorgeschlagen wurde, ist die Übereinstimmung,
temp.
gefolgt von etwas anderem als einem.
, das am Ende der Zeile verankert ist.Welches
temp.txt
am Ende einer Zeile übereinstimmt und es nur durch dastxt
Bit ersetzt.quelle
Ich würde ein Makro schreiben, wobei der Cursor oben links beginnt.
qq4f.dfpq
Dann würde ich den Rest der Zeilen mit auswählen
V
und das Makro auf diesen Zeilen mit ausführen:'<,'>norm!@q
Dies funktioniert nur, wenn das Textformat in Bezug auf die Anzahl der Punkte vor der zweiten Temperatur gleich bleibt.
quelle
n
Statt4f.
wenn ein Dateiname mehr Punkte enthält, kann Ihr Makro fehlschlagen oder Dinge löschen, die nicht gelöscht werden sollten.Nichts hindert Sie daran, zwei reguläre Ausdrücke anstelle von nur einem zu verwenden, dh das erste Vorkommen zu ändern und dann die Spalten auszutauschen :
Könnte nicht besonders klug sein, aber ich finde es sehr lesbar.
quelle
Mein Versuch
quelle