Cum se adaugă numere de linie permanente într-un fișier?

Am un fișier text ca acesta (folosind gVim pe Windows)

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

Vreau să adaug un număr la fiecare linie din fișier. Nu se utilizează :set number, ci pentru a adăuga numărul ca text care precede fiecare linie, după cum urmează, astfel încât numărul să facă parte din fișier.

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

Comentarii

  • awk este probabil instrumentul pentru acest job. Dar ‘ m pe Windows (suspin).
  • Răspuns aici deja , nu contează 🙂
  • Poate .. Sau este mai general?
  • Este ‘ similar, dar nu aș ‘ nu știu ce sunt numerele de linie permanente. În al doilea rând, cealaltă întrebare este despre toate liniile (și răspunsul face asta) pentru gVim pe Windows în mod specific și aceasta este o listă numerotată simplă pentru un singur paragraf numai în vim simplu. id = „89061d7645”>

permanent ” nu indică faptul că tamponul trebuie modificat și că numerele nu sunt ‘ un lucru pur vizual (la fel ca tine). Motivul pentru specificarea gvim pe Windows este evitarea utilităților externe precumcatsaunl, care pot face linii numerice, dar nu sunt ‘ nu este disponibil în general pe Windows (așa cum indică OP din comentariul lor despreawk). Primele două soluții sunt Vim pur. În cele din urmă, toate liniile vs un para este doar o chestiune de selecție a gamei. În mod clar nu este o problemă importantă.

Răspuns

În mod pur Vim:

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

Explicație:

:%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 

Consultați :help \= și :help line().

Utilizarea unei expresii în partea de înlocuire este foarte puternică și FWIW este un punct de intrare destul de bun pentru vimscript.

Comentarii

  • Cum pot adăuga această comandă foarte utilă la o hartă de taste din vimrc?
  • Pentru a ajunge la subiectul de ajutor vim pentru înlocuire: :help sub-replace-expression

Răspuns

Un lucru frumos la macro-urile Vim este că pot recurge (se pot invoca singuri ):

  1. Ștergeți registrul q: qqq
  2. Adăugați numărul la prima linie: ggI1. (nu uitați spațiul!)
  3. Mergeți înapoi la începutul liniei și începeți să înregistrați un macro: 0qq
  4. Copiați numărul:
  5. Mutați în jos o linie și lipiți numărul: +P
  6. Mutați înapoi la începutul liniei și creșteți numărul: 0<c-a>
  7. Mutați-vă înapoi la începutul liniei (astfel încât macro-ul să nu se rupă când ajunge la cifre duble!): 0
  8. Apelați macrocomanda o singură dată, pentru a o face recursivă. În acest moment, nu există încă nimic în registrul q, deci nu se va întâmpla nimic: @q.
  9. Salvați macrocomanda: q
  10. Apelați încă o dată macro și urmăriți scânteile care zboară !: @@

apoi continuați să vă invocați până când ajunge la sfârșitul fișierului.

Puteți utiliza trucul recursiv al macrocomenzii pentru multe alte probleme similare, așa că „este bine să fiți conștienți.

Dacă nu doriți să utilizați o macro recursivă dintr-un anumit motiv, puteți omite pașii 1 și 8 și puteți utiliza un număr pentru a rula macro de mai multe ori, de ex. 100@q va rula macro q de 100 de ori.

Comentarii

  • Lucruri puternice, mă închin măiestriei tale. Macrocomenzile sunt ca magia neagră pentru mine …
  • @ropata, o macro este doar o secvență de comenzi (în cea mai mare parte) în mod normal.
  • @romainl Cred că este mai bine să ne gândim la el ca la o secvență de apăsări de taste .
  • @Rich, poate fi o succesiune de multe lucruri, inclusiv comenzi ex.
  • @romainl Da, ‘ este motivul pentru care cred că ‘ este cel mai bine să îl considerăm drept apăsări de taste. Se redă exact ceea ce tastați pe tastatură (inclusiv, după cum spuneți, ex comenzi), de parcă ați fi introdus totul manual.

Răspuns

Îmi place să folosesc comanda globală vim pentru a îndeplini sarcini de acest gen. Acest lucru se aplică adăugării iterației la începutul unei linii sau modificării unui simbol din text. Arată mai complicat decât celelalte soluții, dar este un model destul de flexibil de utilizat atunci când îl aveți la îndemână și este ușor de modificat fără să vă gândiți prea mult.

În primul rând, alegeți gama dvs. (care linii vă doresc să aplic acest lucru). De obicei folosesc mărci (de ex.ma pe prima linie și mb pe a doua, dar puteți utiliza și numere de linie sau selecție vizuală), apoi introduceți o modificare a următoarea comandă (modificată în prezent pentru cazul dvs. de utilizare)

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

Deconstrucție

:let i=1 

Aceasta setează variabila i cu o valoare de pornire. De obicei, listele încep cu 1, așa că „m setez i la 1.

| 

Bara pornește o nouă comandă

"a,"b 

Aceasta setează intervalul comenzii următoare. Mă duc de la marca a la marca b , care ar fi setată pe prima și ultima linie din lista dvs.

g/^/ 

Aceasta este comanda globală. Acesta caută în fișier (sau interval) o expresie regulată dată și va executa restul liniei de comandă pe fiecare dintre liniile potrivite. „Potrivește fiecare linie căutând„ începutul rândului ”. Dacă ați avea text precum

Item some txt other text Item second item whatever Item third 

și doriți doar să puneți aceste etichete în fața Item și ignorați celelalte linii, faceți g/Item/ sau g/^Item/ în loc (presupunând textul literal al articolului )

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

Aceasta execută expresia regulată pentru a înlocui începutul liniei cu valoarea i concatenată cu a .. În general, puteți face acest lucru pentru orice (înlocuiți eticheta Item cu numărul, de exemplu).

|let i=i+1 

Chiar dacă bara pornește o nouă comandă, ea configurează o a doua comandă pentru a rula în cadrul comenzii globale, în loc de după finalizarea globală. Rezultatul este că incrementăm i înainte ca următoarea linie să fie procesată de g. Iată un alt loc de flexibilitate. Modificarea lui i poate fi orice (incre 2, apelați o funcție care generează următorul element al secvenței Fibonacci, oricare ar fi).

Răspuns

Adăugați numere la toate liniile

Este posibil să utilizați :%!nl -ba sau :%!cat -n comenzi care vor adăuga numere de linie la toate liniile.

În Windows, „Trebuie să aveți Cygwin / MSYS / SUA instalat.

Adăugați numere la liniile selectate

Pentru a adăuga numere numai pentru liniile selectate, vă rugăm să le selectați în modul vizual ( v și cursoare), apoi, când ați terminat – executați comanda: :%!nl (ignorați liniile goale) sau :%!cat -n (linii goale incluse).

Formatare

Pentru a elimina spații suplimentare, selectați-le în bloc vizual ( Ctrl + v ) și eliminați-le ( x ).

Pentru a adăuga câteva caractere (., :, ) după numere, selectați-le în bloc vizual ( Ctrl + v ), apoi adăugați caracterul ( A , tastați caracterul, apoi terminați cu Esc ).

Comentarii

  • Aceasta nu oferă aceeași formatare ca cea dată în întrebare. Cu toate acestea, îmi place simplitatea soluției.
  • @KarlYngveLerv å g Mulțumesc, am inclus asta în răspuns.

Răspuns

O modificare a răspunsului romainl :

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

Aceasta nu va doar adăuga numere de linie, ci va înlocui ieșirea numerelor de linie dacă acestea sunt deja acolo. Dacă, dacă ați inserat o linie la jumătatea drumului, va renumerota totul așa cum era de așteptat.

Acest lucru funcționează prin înlocuirea oricărui număr urmat de un. Și un spațiu la începutul liniei cu un număr nou. . Acest lucru se va rupe în mod evident dacă aveți o linie care începe deja cu acest model, așa că utilizați cu gândire.

Partea adăugată:

  • ^ – Începutul liniei
  • \( – Începeți un subgrup nou
  • \d\+ – Potriviți o cifră o dată sau mai multe
  • \. – Potriviți un punct (.) și un spațiu .
  • \) – Sfârșitul subgrupului
  • \? – Faceți grupul opțional, astfel încât să funcționeze ca înainte, dacă nu există încă niciun număr pe această linie.

Sugestie pentru bonus :
Pentru a elimina numerele de linie, puteți utiliza același model cu partea de repalce goală:

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

Răspuns

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

Aceasta numerotează primele două linii și puteți apăsa @q pentru a numera liniile ulterioare (sau tastați ex. 18@q dacă doriți să numărați 20 de linii în total).

Explicație:

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 

Avantajul este că nu necesită comenzi externe, ceea ce este util dacă sunteți lucrul cu Vim pe Windows, de exemplu.

Comentarii

  • După ce tastați 1. <esc>h vă aflați pe a doua coloană, nu prima coloană. Aș înlocui h cu 0, după care cred că soluția dvs. ar trebui să fie foarte bună.
  • @KarlYngveLerv å g Hopa, a fost o greșeală de eroare. Mulțumesc, am remediat-o.
  • Nicio problemă. Cu toate acestea, încă nu ați actualizat explicația. De asemenea: pe multe tastaturi, ^ așteaptă un al doilea caracter pentru a permite combinații de tastare precum ^a -> â. Sunt în continuare de acord cu cea mai bună soluție, dar cred că ar trebui menționat și acest lucru.

Răspuns

I cred că răspunsul ales este cel mai bun, dar în sprit de varietate, voi oferi o alternativă folosind un program extern:

:%!cat -n 

Acest lucru vă va filtra întregul tampon (așa cum este notat cu %) prin intermediul programului extern, cat, unde -n steagul prevede fiecare linie de intrare cu un număr de linie.

Aceasta, desigur, necesită instalarea cat, ceea ce este adevărat pentru (probabil) toate Unix -like systems.

Consultați :help :range! pentru mai multe detalii despre filtrarea prin programe externe.

Comentarii

  • Îmi dau seama că persoana care solicită folosește gVim pe Windows, așa că această soluție probabil că nu va funcționa acolo. Cu toate acestea, cred că oferă în continuare unele oportunități pentru alții t o învățați de la el.
  • Dacă ‘ ați instalat msysgit și ați adăugat acest lucru la PATH (IIRC it ‘ este o opțiune de instalare), această soluție ar trebui să funcționeze și pe Windows.
  • cat -n nu este POSIX, dar nl este, deci ar putea fi un opțiune mai bună.

Răspunsul

O soluție puțin amăgitoare ar putea fi următoarea (tot ceea ce este scris între și> urmează să fie inserate după ce apăsați Ctrl + v ):

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

Deconstrucție

:%normal {commands} 

rulează comanda de mod normal pe fiecare linie specificată de interval, în acest caz fiecare linie

:redir @" 

redirecționează fiecare ieșire realizată de comenzile ex către bufferul fără nume.

:.= 

este o comandă ex care scoate linia curentă număr (cu o linie nouă precedentă din păcate)

:redir END 

încetează redirecționarea către bufferul fără nume

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

inserează conținutul bufferului fără nume cu un. și o filă în fața fiecărei linii și iese din modul inserare.

kdd 

merge cu o linie în sus și elimină linia nouă care este rezultatul:. = comanda.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *