Jak dodać stałe numery wierszy do pliku?

Mam taki plik tekstowy (używam gVim w systemie Windows)

foo bar baz quux corge grault garply waldo fred plugh [...150 more lines...] xyzzy thud 

Chcę dodać liczbę do każdego wiersza w pliku. Nie używamy :set number, ale dodajemy liczbę jako tekst poprzedzający każdy wiersz w następujący sposób, aby numer był częścią pliku.

1. foo bar baz quux 2. corge grault garply 3. waldo fred plugh [...~150 more lines...] 155. xyzzy thud 

Komentarze

  • awk jest prawdopodobnie narzędziem do tego zadania. Ale ja ' mw systemie Windows (westchnienie).
  • Odpowiedziałem już tutaj , nieważne 🙂
  • Może .. A może to bardziej ogólne?
  • Jest ' podobnie, ale nie ' nie wiem, jakie są stałe numery linii. Po drugie, drugie pytanie dotyczy wszystkich wierszy (a odpowiedź to robi) specjalnie dla gVim w Windows i jest to prosta numerowana lista tylko dla jednego akapitu w zwykłym vimie.
  • Cóż, myślę, że ten post używa ” permanent ” ot wskazują, że bufor ma zostać zmodyfikowany, a liczby nie są ' t jakaś czysto wizualna rzecz (taka sama jak ty). Powodem określenia gvim w systemie Windows jest uniknięcie zewnętrznych narzędzi, takich jak cat lub nl, które mogą wykonywać wiersze liczbowe, ale nie mają ' t ogólnie dostępne w systemie Windows (jak wskazuje OP na podstawie ich komentarza na temat awk). Dwa najlepsze rozwiązania to czysty Vim. Wreszcie, wszystkie linie kontra jeden para to tylko kwestia wyboru zakresu. Z pewnością nie jest to duży problem.

Odpowiedź

W czystym stylu Vima:

:%s/^/\=line(".").". " 

Wyjaśnienie:

:%s/^/ " the substitution will be applied to the beginning of every line \= " the rest of the replacement part is an expression line(".").". " " the expression returns the current line number concatenated with a dot and a space 

Zobacz :help \= i :help line().

Używanie wyrażenia w części zamiennej jest bardzo potężne, a FWIW jest całkiem dobrym punktem wejścia do vimscript.

Komentarze

  • Jak mogę dodać to bardzo przydatne polecenie do mapy klawiszy w vimrc?
  • Aby dostać się do tematu pomocy vim na temat podstawiania: :help sub-replace-expression

Odpowiedź

Jedną z fajnych rzeczy w makrach Vima jest to, że mogą się powtarzać (mogą się wywoływać ):

  1. Wyczyść rejestr q: qqq
  2. Dodaj numer do pierwszej linii: ggI1. (nie zapomnij o spacji!)
  3. Wróć na początek wiersza i zacznij nagrywać makro: 0qq
  4. Skopiuj numer:
  5. Przesuń wiersz w dół i wklej numer: +P
  6. Przejdź z powrotem na początek wiersza i zwiększ liczbę: 0<c-a>
  7. Wróć na początek wiersza (aby makro nie pękało, gdy osiąga podwójne cyfry!): 0
  8. Wywołaj makro raz, aby było rekurencyjne. W tym momencie w rejestrze q nadal nic nie ma, więc nic się nie stanie: @q.
  9. Zapisz makro: q
  10. Wywołaj makro jeszcze raz i zobacz, jak lecą iskry !: @@

Makro będzie następnie kontynuuj wywoływanie samego siebie, aż dotrze do końca pliku.

Możesz użyć rekurencyjnej sztuczki makr do wielu innych podobnych problemów, więc dobrze jest być świadomym.

Jeśli z jakiegoś powodu nie chcesz używać makra rekurencyjnego, możesz pominąć kroki 1 i 8 i użyć licznika , aby uruchomić makro wiele razy, np. 100@q uruchomi makro q 100 razy.

Komentarze

  • Potężne rzeczy, kłaniam się twojemu mistrzostwu. Makra są dla mnie jak czarna magia …
  • @ropata, makro to tylko sekwencja (głównie) poleceń trybu normalnego.
  • @romainl Myślę, że to lepiej myśleć o tym jako o sekwencji naciśnięć klawiszy .
  • @Rich, może to być sekwencja wielu rzeczy, w tym poleceń ex.
  • @romainl Tak, to ' dlatego uważam, że ' najlepiej jest myśleć o tym jako o naciśnięciu klawisza. Odtwarza dokładnie to, co wpisujesz na klawiaturze (w tym, jak mówisz, polecenia ex), tak jakbyś wpisał to wszystko ręcznie.

Odpowiedz

Lubię używać globalnego polecenia vim do wykonywania takich zadań. Dotyczy to dodawania iteracji na początku wiersza lub modyfikacji symbolu w tekście. Wygląda na bardziej skomplikowane niż inne rozwiązania, ale jest dość elastycznym wzorcem do użycia, gdy masz go pod ręką i można go łatwo zmodyfikować bez większego zastanowienia.

Najpierw wybierz zakres (który chcesz to zastosować). Zwykle używam znaków (np.ma w pierwszym wierszu i mb w drugim, ale możesz też użyć numerów wierszy lub selekcji wizualnej), a następnie wprowadź modyfikację następujące polecenie (obecnie dostosowane do Twojego przypadku użycia)

:let i=1|"a,"bg/^/s/^/\=i.". "/|let i=i+1 

Dekonstrukcja

:let i=1 

Spowoduje to ustawienie zmiennej i z wartością początkową. Zwykle listy zaczynają się od 1, więc ustawiam i na 1.

| 

Pasek rozpoczyna nowe polecenie

"a,"b 

Ustawia zakres następnego polecenia. Przechodzę od znaku a do oznaczenia b , które zostanie ustawione w pierwszym i ostatnim wierszu listy.

g/^/ 

To jest polecenie globalne. Przeszukuje plik (lub zakres) pod kątem danego wyrażenia regularnego i wykonuje resztę wiersza poleceń w każdej linii, która została dopasowana. Dopasowuję każdy wiersz, wyszukując „początek wiersza”. Jeśli masz tekst taki jak

Item some txt other text Item second item whatever Item third 

i chcesz umieścić te etykiety tylko przed Item i zignoruj pozostałe wiersze, zamiast tego wykonaj g/Item/ lub g/^Item/ (przyjmując literalny tekst pozycji )

s/^/\=i.". "/ 

Powoduje to wykonanie wyrażenia regularnego w celu zastąpienia początku wiersza wartością i połączoną z a .. Generalnie możesz to zrobić na wszystko (na przykład zastąp etykietę Item numerem).

|let i=i+1 

Mimo że pasek uruchamia nowe polecenie, ustawia drugie polecenie, które ma być uruchamiane w ramach polecenia globalnego, zamiast po jego zakończeniu. W rezultacie zwiększamy i zanim następna linia zostanie przetworzona przez g. Oto kolejne miejsce elastyczności. Modyfikacja i może być dowolna (zwiększ o 2, wywołaj funkcję, która generuje następny element ciągu Fibonacciego, cokolwiek).

Odpowiedź

Dodaj liczby do wszystkie linie

Można użyć :%!nl -ba lub :%!cat -n , które dodadzą numery linii do wszystkich linii.

W systemie Windows „ve mieć zainstalowany Cygwin / MSYS / SUA.

Dodaj numery do wybranych linii

Aby dodać numery tylko dla wybranych linii, wybierz je w tryb wizualny ( v i kursory), a po zakończeniu – wykonaj polecenie: :%!nl (ignoruj puste linie) lub :%!cat -n (łącznie z pustymi wierszami).

Formatowanie

Aby usunąć dodatkowe spacje, zaznacz je w bloku wizualnym ( Ctrl + v ) i usuń je ( x ).

Aby dodać kilka znaków (., :, ) po liczbach, zaznacz je w bloku wizualnym ( Ctrl + v ), a następnie dołącz znak ( A , wpisz znak, a następnie zakończ Esc ).

Komentarze

  • To nie daje takiego samego formatowania jak podane w pytaniu. Jednak podoba mi się prostota rozwiązania.
  • @KarlYngveLerv å g Dziękuję, zawarłem to w odpowiedzi.

Odpowiedź

Modyfikacja odpowiedzi romainl :

:%s/^\(\d\+\. \)\?/\=line(".").". " 

To nie tylko doda numery linii, ale także zastąpi numery linii wyjściowych, jeśli już tam są. Of, jeśli wstawiłeś wiersz w połowie drogi, numeracja wszystkiego zostanie zmieniona zgodnie z oczekiwaniami.

Działa to poprzez zastąpienie dowolnej liczby, po której następuje a. I spacja na początku wiersza, nową liczbą . To oczywiście się zepsuje, jeśli masz linię, która już zaczyna się od tego wzorca, więc używaj jej z przemyśleniem.

Dodana część:

  • ^ – początek linii
  • \( – Rozpocznij nową podgrupę
  • \d\+ – Dopasuj cyfrę raz lub więcej razy
  • \. – Dopasuj kropkę (.) i spacją .
  • \) – Zakończ podgrupę
  • \? – Ustaw grupę jako opcjonalną, aby działała jak poprzednio, jeśli nie ma jeszcze numeru w tej linii.

Dodatkowa wskazówka :
Aby usunąć numery wierszy, możesz użyć tego samego wzorca z pustą częścią repalce:

:%s/^\(\d\+\. \)\?// 

Odpowiedź

I1. <esc>^qqyWjP^<C-a>q 

To numeruje pierwsze dwie linie i możesz nacisnąć @q aby ponumerować kolejne linie (lub wpisz np. 18@q, jeśli chcesz liczyć łącznie 20 wierszy).

Wyjaśnienie:

I1. <esc> Number the first line hqq Go back to the start of the line and start recording a macro yWjP Copy the line number to the next line ^<C-a> Increment the next line"s line number q Finish recording 

Zaletą tego jest to, że nie wymaga żadnych zewnętrznych poleceń, co jest przydatne, jeśli na przykład praca z Vimem w systemie Windows.

Komentarze

  • Po wpisaniu 1. <esc>h jesteś na druga kolumna, a nie pierwsza kolumna. Zamieniłbym h na 0, po czym myślę, że twoje rozwiązanie powinno być bardzo dobre.
  • @KarlYngveLerv å g Ups, to była literówka. Dzięki, naprawiłem to.
  • Żaden problem. Jednak nadal nie zaktualizowałeś wyjaśnienia. Ponadto: na wielu klawiaturach ^ czeka na drugi znak, aby umożliwić wpisywanie kombinacji, takich jak ^a -> â. Wciąż zgadzam się, że to najlepsze rozwiązanie, ale myślę, że należy również wspomnieć o tym.

Odpowiedź

I myślę, że wybrana odpowiedź jest najlepsza, ale w duchu różnorodności zaproponuję alternatywę za pomocą zewnętrznego programu:

:%!cat -n 

To przefiltruje cały bufor (zgodnie z oznaczeniem %) za pośrednictwem programu zewnętrznego, cat, gdzie -n flaga poprzedza każdy wiersz wejścia numerem wiersza.

Oczywiście wymaga to zainstalowania cat, co jest prawdą dla (prawdopodobnie) wszystkich systemów Unix -podobnych systemów.

Sprawdź :help :range!, aby uzyskać więcej informacji na temat filtrowania przez programy zewnętrzne.

Komentarze

  • Zdaję sobie sprawę, że pytający używa gVim w systemie Windows, więc to rozwiązanie prawdopodobnie ' nie zadziała. Jednak myślę, że nadal zapewnia pewne możliwości innym t ucz się z tego.
  • Jeśli ' zainstalowałeś msysgit i dodałeś to do swojej PATH (IIRC it ' jest opcją instalacji), to rozwiązanie powinno również działać w systemie Windows.
  • cat -n nie jest POSIX, ale nl tak, więc może to być lepsza opcja.

Odpowiedź

Trochę hakerskie rozwiązanie może być następujące (wszystko zapisane między i> należy wstawić po naciśnięciu Ctrl + v ):

:%normal :redir @"<Enter>:-=<Enter>:redir END<Enter>I<C-R>".<Tab><Esc>kdd 

Dekonstrukcja

:%normal {commands} 

uruchamia polecenie trybu normalnego w każdej linii określonej przez zakres, w tym przypadku w każdej linii

:redir @" 

przekierowuje każde wyjście wykonane przez polecenia ex do nienazwanego bufora.

:.= 

jest poleceniem ex, które wyświetla bieżącą linię numer (niestety z poprzedzającym znakiem nowej linii)

:redir END 

przestaje przekierowywać do nienazwanego bufora

I<C-R>".<Tab><Esc> 

wstawia zawartość nienazwanego buforu z rozszerzeniem. i tabulator na początku każdego wiersza i wychodzi z trybu wstawiania.

kdd 

przechodzi o jedną linię w górę i usuwa znak nowej linii, który jest wynikiem:. = polecenie.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *