Mai mult
Extras subșir în Bash
Având un nume de fișier în formă someletters_12345_moreleters.ext
, vreau sa extrag 5 cifre și le-a pus într-o variabilă.
Deci, pentru a sublinia ideea, am un fisier cu x numărul de caractere apoi o perioada de cinci cifre secvență înconjurat de o singură subliniere pe fiecare parte apoi de un alt set de x numărul de caractere. Vreau să iau număr de 5 cifre și a pus într-o variabilă.
Sunt foarte interesat de numărul de moduri diferite în care acest lucru poate fi realizat.
680
20
Dacă x este constantă, următorul parametru de expansiune efectuează subșir de extracție:
în cazul în care 12 este offset (zero-based) și 5 este lungimea
Dacă subliniaza jurul cifre sunt doar cele de la intrare, puteți benzi pe prefix și sufix (respectiv) în două etape:
Dacă există și alte subliniază, l's, probabil, posibil, oricum, deși mai complicat. Dacă cineva știe cum de a efectua ambele expansion-uri într-o singură expresie, am'd vrea să știe.
Ambele soluții prezentate sunt pur bash, cu nici un proces de depunere a icrelor implicate, prin urmare, foarte rapid.
Folosi cut:
Mai generic:
Generic soluție în cazul în care numărul poate fi oriunde în nume de fișier, folosind prima de astfel de secvențe:
O altă soluție pentru a extrage exact o parte a unei variabile:
Dacă numele fișierului dvs. întotdeauna au format
stuff_digits_...
poti folosi awk:Încă o soluție pentru a elimina totul, cu excepția cifre, utilizare
doar încercați să utilizați
cut-c startIndx-stopIndx
În cazul în care cineva vrea mai riguroase informații, puteți căuta, de asemenea, că în om bash astfel de prognoze
Rezultatul:
Clădirea de pe jor's raspuns (care nu't de lucru pentru mine):
Am'm-a surprins acest lucru pur bash soluție n't veni:
Probabil că doriți să resetați IFS pentru ce valoare a fost înainte, sau `unset FI după aceea!
Aici's cum am'd face:
Notă: cele de mai sus este o expresie regulată și este limitată la scenariu specific de cinci cifre înconjurat de subliniere. Schimba expresia regulată dacă aveți nevoie de diferite de potrivire.
Următoarele cerințe
Am găsit niște
grep
moduri în care pot fi utile:sau mai bine
Și apoi, cu
-Po
sintaxa:Fără nici o sub-procese puteți:
O foarte mică variantă de acest lucru va lucra, de asemenea, în ksh93.
Dacă ne concentrăm în conceptul de:
"O (una sau mai multe) cifre"
Am putea folosi mai multe instrumente externe pentru a extrage numere.
Am putea destul de ușor de a șterge toate celelalte personaje, fie sed sau tr:
Dar dacă $numele conține mai multe serii de numere, cele de mai sus va eșua:
Dacă "nume=someletters_12345_moreleters_323_end.ext", atunci:
Avem nevoie de a utiliza expresii regulate (regex). Pentru a selecta numai primul termen (12345 nu 323) în sed și perl:
Dar am putea la fel de bine face direct în bash(1) :
Acest lucru ne permite de a extrage PRIMUL termen de cifre de orice lungime înconjurat de orice alt text/caractere.
Notă:
regex=[^0-9]*([0-9]{5,5}).*$;
se va potrivi numai exact 5 cifre ruleaza. :-)(1): mai repede decât de asteptare un instrument extern pentru fiecare texte scurte. Nu mai rapid decât a face toate de prelucrare în interiorul sed sau awk pentru fișiere mari.
Aici's un prefix-sufix soluție (similar cu soluțiile date de JB și Rodger) care se potrivește primul bloc de cifre și nu depinde de cei din jur subliniază:
Îmi place
sed
's capacitatea de a face cu regex grupe:Un pic mai general opțiune ar fi nu să presupunem că aveți un caracter de subliniere
_
marcajul de început al tău cifre secvență, prin urmare, de exemplu, de separare de pe toate non-numerele pe care le obține înainte de secvența: s/[^0-9]+([0-9]+).*/\1/p`.Mai mult, în cazul în te're nu sunt prea increzator cu regexps:
\1
link-uri către grupul n.1 din regex ieșire (grupa 0 este tot meciul, grupa 1, este un meci între paranteze, în acest caz)Toate scapă
\
sunt acolo pentru a facesed
's regexp de procesare.Dat test.txt este un fișier care conține "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Răspunsul meu va avea mai mult control asupra a ceea ce vrei sa iesi din șir. Aici este codul de pe modul în care puteți extrage
12345
din șirAcest lucru va fi mai eficientă dacă doriți pentru a extrage ceva care are caractere de genul " abc " sau orice caractere speciale cum ar fi
_
sau-
. De exemplu: Dacă șirul este ca asta si vrei tot ce e dupăsomeletters_ și înainte de
_moreleters.ext` :Cu codul meu puteți menționa exact ceea ce vrei. Explicație:
#*
Se va elimina precedent string, inclusiv de potrivire cheie. Aici cheia am menționat este_
%
Se va elimina următorul șir inclusiv de potrivire cheie. Aici cheia am menționat este '_more*'Face unele experimente tine și te-ar găsi interesant.
Ok, aici merge pur Parametru de Substituție cu un șir gol. Avertismentul este că am definit someletters și moreletters ca numai caractere. Dacă acestea sunt alfanumerice, acest lucru nu va funcționa așa cum este.
similar cu substr('abcdefg', 2-1, 3) in php:
Un bash soluție:
Un pic mai târziu, dar tocmai am dat peste această problemă și a constatat următoarele:
Am folosit-o pentru a obține milisecundă rezoluție privind un sistem încorporat care nu au %N pentru data de:
Nu's, de asemenea, bash interna 'expr' comanda: