Puncte:1

Sortați un fișier în funcție de un câmp care începe cu șir

drapel jp

Să presupunem că am un fișier atât de structurat

/home/zz/AUTHORBOOKS/Author-Chomsky-Who-Rules-the-World.epub
/home/zz/AUTHORBOOKS/Author-Cioran-Il-nulla.epub
/home/zz/BOOKS/Author-Artemis-Mathematica-Examples.nb
/home/zz/Books/Author-Zigniwe-Hisory-Medicine.pdf
/home/z1/OLDBOOKS1/OLDBOOKS2/Author-Watanabe-Waterloo.pdf
/home/z2/OLDBOOKS1/OLDBOOKS2/Author-Barbero-Lepanto.epub.pdf

Aș dori un fișier sortat astfel:

/home/zz/BOOKS/Author-Artemis-Mathematica-Examples.nb
/home/z2/OLDBOOKS1/OLDBOOKS2/Author-Barbero-Lepanto.epub.pdf
/home/zz/AUTHORBOOKS/Author-Chomsky-Who-Rules-the-World.epub
/home/zz/AUTHORBOOKS/Author-Cioran-Il-nulla.epub
/home/z1/OLDBOOKS1/OLDBOOKS2/Author-Watanabe-Waterloo.pdf
/home/zz/Books/Author-Zigniwe-History-Medicine.pdf

Adică, alfabetic, conform șirului Autor-...

După cum puteți vedea poziția lui Autor-... nu este constantă.

Cum pot face acest lucru?

FedKad avatar
drapel cn
Această întrebare ar fi mai interesantă dacă nu ar exista un separator (cum ar fi `-`) pentru a începe „key 2”. De exemplu, cum putem sorta folosind numele de fișier _tot_?
waltinator avatar
drapel it
Citiți `man sort` și cartea lui Knuth "Sorting and Searching", vol. 4 din Fundamental Algorithms.
drapel ar
Dacă credeți că unul dintre răspunsuri este corect, acceptați răspunsul făcând clic pe bifa gri âï¸ de lângă acel răspuns și transformați-l în verde â . Acest lucru îi va ajuta pe alții.
Puncte:3
drapel hr

Deși este exagerat pentru exemplul de față din cauza soluție propusă în răspunsul utilizatorului68186, în general ați putea face ceva de genul acesta în GNU awk:

gawk -F/ '
  funcția mycmp(i1,v1,i2,v2) {
    m = split(v1,a);
    n = split(v2,b);
    returnează a[m]"" > b[n]"" ? 1 : a[m]"" < b[n]"" ? -1:0
  }
  {
    linii[NR] = $0
  }
  SFÂRŞIT {
    PROCINFO["sorted_in"] = "mycmp";
    pentru(i în rânduri) linii de imprimare[i]
  }
' dosar

Rețineți că sortează în funcție de valoarea lexicală a tot ce urmează după ultimul / - deci dacă formatul este Autor-<numele autorului>-<titlu>.<extensie> o sa fie

  • coarda fixă Autor- (care nu are efect, deoarece are aceeași greutate pentru toate liniile); atunci
  • <numele autorului>-; atunci
  • <titlu>.; atunci
  • <extension>

Acest lucru este similar cu GNU feleste simplu KEYDEF -t- -k2 funcționează, adică cheia de sortare efectivă începe de la <author name> și continuă până la capătul liniei.

Un delimitator explicit este omis din Despică apeluri astfel încât să moștenească valoarea de FS, ceea ce facilitează schimbarea pentru sistemele care utilizează un separator de cale diferit. Șirurile goale atașate "" în mycmp funcția forțează comparația lexicală chiar dacă numele fișierelor sunt numerice - vezi de exemplu Cum se convertește awk între șiruri și numere


Dacă preferați să rămâneți cu fel comandă, puteți folosi GNU awk Comunicații bidirecționale cu un alt proces la:

  • duplicați ultimul /-câmp separat la începutul șirului
  • trece rezultatul la a fel comanda
  • citiți înapoi rezultatul sortat, eliminați prefixul duplicat și imprimați

adică

gawk -F/ '
  ÎNCEPE {OFS=FS; cmd = "sortare -d"} 
  {printați $NF $0 |& cmd} 
  SFÂRŞIT {
    close(cmd,"la"); 
    while(cmd |& getline){$1 = ""; imprimare};
    close(cmd,"de la")
  }
' dosar

Există un pic de înșelăciune aici în sensul că căile absolute (liniile încep cu /) implică un câmp inițial gol; pentru a gestiona căile relative pe care ar trebui să le schimbați imprimați $NF $0 la imprimați $NF, $0 pentru a insera separatorul „lipsă” și apoi poate utilizați o expresie regex sub() în loc de cel mai simplu $1 = "" pentru a îndepărta elementul conducător.

Pe lângă faptul că ar putea fi mai rapid/mai eficient în memorie decât cel pur bălălău soluție, aceasta permite altele fel opțiuni care trebuie adăugate direct ex. cmd = "sortare -d -t " FS " -k1,1r" .

drapel ar
Minunat! Nu prea urmăresc ce se întâmplă în funcția „mycmp”. Îmi puteți indica un tutorial web? Mulțumiri!
drapel hr
Funcțiile de sortare personalizate @user68186 sunt discutate în Ghidul utilizatorului GNU Awk la [Controlling Array Traversal](https://www.gnu.org/software/gawk/manual/gawk.html#Controlling-Array-Traversal) BTW, vă rugăm să vă întoarceți comentează într-un răspuns!
drapel ar
Mulțumesc pentru link, îl înțeleg puțin mai bine, dar sunt multe de învățat în `gawk`. Și așa cum ați dorit, mi-am transformat comentariul într-un răspuns. :)
drapel ar
+1 pentru explicația adăugată! Acum un pic pe `return a[m]"" > b[n]""? 1: a[m]""
drapel hr
@user68186 sunt doar două [condiționale ternare](https://www.gnu.org/software/gawk/manual/gawk.html#Conditional-Exp) într-un trenci
Puncte:3
drapel ar

Încercați următoarele bash comanda:

sortare -t- -d -k2 -o output.txt input.txt

Are patru opțiuni plus numele fișierului de intrare input.txt. Dacă acest fișier nu se află în directorul curent, va trebui să furnizați fișierul calea/la/dosarul/input.txt. Opțiunile și argumentele lor sunt următoarele:

  • -t marchează separatorul de câmp. Folosim - ca separator, astfel încât totul înainte și după - sunt considerate coloane separate.
  • -d indică sortarea dicționarului. De exemplu, Apple este înaintea Berry.
  • -k2 indică coloana după care se sortează, în acest caz a doua coloană. Rețineți că prima coloană este totul înainte de prima -. De exemplu, /home/zz/CĂRȚI/Autor. A doua coloană este între prima și a doua -, acesta este, Artemis.
  • -o output.txt redirecționează rezultatul sortat către un fișier și nu către terminal.

Sper că acest lucru vă ajută

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.