/ / Wie würde ich einen VIM- oder Vi-Befehl erstellen, um den gesamten Text nach einem bestimmten Zeichen für jede Zeile in einer Textdatei zu löschen? - regex, vim, vi, ersetzen

Wie würde ich einen VIM- oder Vi-Befehl erstellen, um den gesamten Text nach einem bestimmten Zeichen für jede Zeile in einer Textdatei zu löschen? - regex, vim, vi, ersetzen

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