Szenario:
- Ich habe eine Textdatei mit Pipe (wie in der
|
Zeichen) abgegrenzte Daten. - Jedes Datenfeld in den Pipe-abgegrenzten Feldern kann eine variable Länge haben, so dass das Zählen der Zeichen nicht funktioniert (oder eine Art von Teilzeichenfolgefunktion verwendet wird, falls diese sogar in Vim existiert).
Ist es möglich, alle Daten mit Vim / Vi zu löschen?von der zweiten Leitung bis zum Ende der Zeile für die gesamte Datei? Es gibt ungefähr 150.000 Zeilen, also würde das manuell nur für einen Masochisten attraktiv sein ...
z.B.
Ändern Sie die folgenden Zeilen von:
1111|random sized text 12345|more random data la la la|1111|abcde
2222|random sized text abcdefghijk|la la la la|2222|defgh
3333|random sized text|more random data|33333|ijklmnop
zu:
1111|random sized text 12345
2222|random sized text abcdefghijk
3333|random sized text
Ich bin mir sicher, dass das irgendwie möglich ist ... hoffe ich.
TIA
UPDATE: Ich hätte erwähnen sollen, dass ich das unter Windows XP ausführe, also habe ich keinen Zugriff auf einige der erwähnten * nix-Befehle (CUT wird unter Windows nicht erkannt).
Antworten:
30 für die Antwort № 1:%s/^v([^|]+|[^|]+)|.*$/1/
18 für die Antwort № 2
Sie können auch ein Makro aufzeichnen:
qq02f | Djq
und dann können Sie es mit 100 @ q abspielen, um das Makro für die nächsten 100 Zeilen auszuführen.
Makro Erklärung:
- qq - Startet die Makroaufnahme
- 0 - Gehe zum ersten Zeichen der Zeile
- 2f | - finde das zweite Vorkommen von | Zeichen auf der Linie
- D - Löschen Sie den Text nach der aktuellen Position bis zum Ende der Zeile
- j - Gehe zur nächsten Zeile
- q - beendet die Makroaufnahme
8 für die Antwort № 3
Wenn Sie nicht vim verwenden müssen, wäre eine andere Alternative der Unix-Befehl "cut".
cut -d "|" -f 1-2 file > out.file
4 für die Antwort № 4
Nur ein weiterer Weg, um das Gleiche zu tun:
%s/^(.{-}|){2}zs.*//
%s/^(.{-}zs|){2}.*// " if you want to remove the 2nd pipe as well
Dieses Mal passt die Regex so wenig wie möglich ({-}) Zeichen, die von einer Pipe gefolgt werden, und zweimal ({2}), sie werden ignoriert (zs) um alle folgenden zu ersetzen (zs) Text durch nichts.
3 für die Antwort № 5
Anstelle der Substitution kann man das verwenden :normal
Befehl zum Wiederholen einer Sequenz von zwei Befehlen im normalen Modus, die zum zweiten springen |
Zeichen und Löschen alles andere bis zum Ende der Linie.
:%norm!2f|D
2 für die Antwort № 6
Verwenden Sie: Befehl, um einen Benutzerbefehl zu erstellen, den Sie einfach ausführen können.
:command -range=% YourNameHere <line1>,<line2>s/^v([^|]+|[^|]+)|.*$/1/
1 für die Antwort № 7
Sie können auch Folgendes tun:
:%s/^([^|]+|[^|]+)|.*$/1/g
1 für die Antwort № 8
benutze awk.
awk -F"|" "{$0=$1"|"$2}1" file
0 für die Antwort № 9
Ich habe festgestellt, dass Vim nicht sehr gut im Umgang mit sehr großen Dateien ist. Ich bin mir nicht sicher, wie groß deine Datei ist. Vielleicht würden Katze und Katze zusammen besser funktionieren.
0 für die Antwort № 10
Hier ist eine Sed-Lösung:
sed -e "s/^([^|]*|[^|]*).*$/1/"
0 für die Antwort № 11
Dadurch werden alle Zeilen im Puffer (1, $) durchgeschnitten, um den Job auszuführen.
:1,$!cut -d "|" -f 1-2
Versuche es mit
:.!cut -d "|" -f 1-2
Um es nur in der aktuellen Zeile zu tun.
0 für die Antwort № 12
Warum vim benutzen?
Warum nicht einfach tun
cat my_pipe_file | cut -d"|" -f1-2