/ / Jak utworzyć polecenie VIM lub Vi, aby usunąć cały tekst po określonym znaku dla każdej linii w pliku tekstowym? - regex, vim, vi, zamień

Jak utworzyć polecenie VIM lub Vi, aby usunąć cały tekst po określonym znaku dla każdej linii w pliku tekstowym? - regex, vim, vi, zamień

Scenariusz:

  • Mam plik tekstowy, który ma potok (jak w | znak) rozdzielone dane.
  • Każde pole danych w polach rozdzielanych potokami może mieć różną długość, więc zliczanie znaków nie będzie działać (lub przy użyciu jakiejś funkcji podciągu ... jeśli nawet istnieje w Vimie).

Czy jest to możliwe, używając Vim / Vi do usunięcia wszystkich danychod drugiej rury do końca linii dla całego pliku? Istnieje około 150 000 linii, więc zrobienie tego ręcznie byłoby atrakcyjne tylko dla masochisty ...

na przykład

Zmień następujące linie z:

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

do:

1111|random sized text 12345
2222|random sized text abcdefghijk
3333|random sized text

Jestem pewien, że można to jakoś ... mam nadzieję.

TIA

AKTUALIZACJA: Powinienem wspomnieć, że uruchamiam to w systemie Windows XP, więc nie mam dostępu do niektórych wymienionych poleceń * nix (CUT nie jest rozpoznawany w systemie Windows).

Odpowiedzi:

30 dla odpowiedzi nr 1
:%s/^v([^|]+|[^|]+)|.*$/1/

18 dla odpowiedzi nr 2

Możesz także nagrać makro:

qq02f | Djq

a następnie będziesz mógł zagrać w 100 @ q, aby uruchomić makro w następnych 100 liniach.

Objaśnienie makr:

  • qq - rozpoczyna nagrywanie makr
  • 0 - przejdź do pierwszego znaku linii
  • 2f | - znajdź drugie wystąpienie | postać na linii
  • re - usuń tekst po aktualnej pozycji na końcu wiersza
  • jot - przejdź do następnej linii
  • q - kończy nagrywanie makr

8 dla odpowiedzi nr 3

Jeśli nie będziesz musiał używać vima, inną alternatywą będzie polecenie unix "cut".

cut -d "|" -f 1-2 file > out.file

4 dla odpowiedzi № 4

Kolejny sposób na zrobienie tego samego:

%s/^(.{-}|){2}zs.*//
%s/^(.{-}zs|){2}.*// " if you want to remove the 2nd pipe as well

Tym razem wyrażenie regularne dopasowuje jak najmniej znaków ({-}), po których następuje potok i dwa razy ({2}), są one ignorowane (zs), aby zastąpić wszystkie następne (zs) tekst po nic.


3 dla odpowiedzi № 5

Zamiast substytucji można użyć :normal polecenie powtórzenia sekwencji dwóch poleceń trybu normalnego przeskakujących do drugiego | znak i usuwanie wszystko inne do końca linii.

:%norm!2f|D

2 dla odpowiedzi № 6

Użyj: polecenia, aby wykonać polecenie użytkownika, które możesz łatwo uruchomić.

:command -range=% YourNameHere <line1>,<line2>s/^v([^|]+|[^|]+)|.*$/1/

1 dla odpowiedzi № 7

Możesz także:

:%s/^([^|]+|[^|]+)|.*$/1/g

1 dla odpowiedzi № 8

użyj awk.

awk -F"|" "{$0=$1"|"$2}1" file

0 dla odpowiedzi № 9

Odkryłem, że vim nie jest świetny w obsłudze bardzo dużych plików. Nie jestem pewien, jak duży jest twój plik, może kot i sed razem będą działać lepiej.


0 dla odpowiedzi № 10

Oto rozwiązanie sed:

sed -e "s/^([^|]*|[^|]*).*$/1/"

0 dla odpowiedzi № 11

Spowoduje to przefiltrowanie wszystkich linii w buforze (1, $) przez cięcie, aby wykonać zadanie.

:1,$!cut -d "|" -f 1-2

Spróbuj z

:.!cut -d "|" -f 1-2

Aby zrobić to tylko w bieżącej linii.


0 dla odpowiedzi № 12

Dlaczego warto korzystać z vima?

Dlaczego po prostu nie robić

cat my_pipe_file | cut -d"|" -f1-2