{$var%Pattern} Remove from $var the shortest part of $Pattern that matches the back end of $var.
{$var%%Pattern} Remove from $var the longest part of $Pattern that matches the back end of $var.[/code]
Pošto se koristio % operator (${base%.*}) znači idemo s desne strane, dok ne naiđemo na prvu tačku.
Radi i sa razmacima, zarezima i sl u nazivu datoteka (tako da fakat ne kontam “poentu”)
Anyway, može se sad izmisliti dosta razloga zašto taj i taj pristup ne bi radio, a neki super cool regularni izraz (po narodski kobasica) radi uvijek i zauvijek, ali mislim da u programiranju nema apsolutnih istina, samo previše načina da se uradi jedna stvar
Mislio sam npr. na slučaj
Enterprise 1x03.Fight or flight.The Second Edition.srt
Tvoj kod bi protumačio “Enterprise 1x03.Fight or flight” kao prefix a “The Second Edition” kao base. Rješenje je da se ide s lijeve strane za prefix a s desne za ekstenziju, ali je sve to skupa IMHO totalno neprirodan način razmišljanja. Prednost regexa je što možeš zadati format koji mora zadovoljiti čitav string umjesto da “ideš sa neke strane”. Uostalom šta fali jednom malom regex tutorijalu Sasvim je svejedno da li koristiš kobasicu ili jedan jedini znak ako ne znaš šta taj znak znači
Pa opet ne čitaš šta piše, da pojednostavimo, probaj:
$ A="Enterprise 1x03.Fight or flight.The Second Edition.srt"
$ echo ${A%.*}
Enterprise 1x03.Fight or flight.The Second Edition
$ echo ${A%.*.*}
Enterprise 1x03.Fight or flight
Što će nam regexi kad padamo na jednostavnim stvarima (griješiti je ljudski)
Prednost regexa u ovom konkretnom slučaju jeste da je komplikovaniji. Vjerujem da postoji i vrijeme i mjesto za regexe (u paklu?, šala mala), ali u dosta slučajeva upotreba regularnih izraza kosi se sa KISS principom. Ruglarni izrazi su clever (u Python smislu te riječi).
Ne kontam kakve veze ima ovaj zadnji komad koda sa činjenicom da tvoj program ne radi (ni prvi ni drugi) sa primjerom koji sam dao?
/home/user/tmp> touch "Enterprise 1x03.Fight or flight.The Second Edition.srt"
/home/user/tmp> touch "Enterprise 1x03.avi"
/home/user/tmp> for f in *.srt; do mv "${f%.*.*}.avi" "${f%.*}.avi"; done
mv: cannot stat `Enterprise 1x03.Fight or flight.avi': No such file or directory
Promijenio si osnovne postavke primjera, ekvivalentno tome moraju se promijeniti patterni u kodu:
for f in *.srt; do mv "${f%.*.*.*}.avi" "${f%.*}.avi"; done
ili
for f in *.srt; do mv "${f%%.*.*}.avi" "${f%.*}.avi"; done
Znači možemo koristiti ili % ili %% kako nam paše. But that’s not the point, ti uporno odbijaš piznati da su u konkretnom slučaju regularni izrazi totalni overkill, te da nema nekih imaginarnih problema sa brojem tačaka, razmacima i sl. kad se radi direktno u bashu.
Edit:
P.S. prvobitno rješenje je pisano za konkretan problem, čovjek se već izjasnio da radi, šta pokušavaš dokazati?
Obrazloži zašto su overkill? Ja recimo nikad nisam čuo za operatore ${…%…} i ${…%%…} do ovih tvojih primjera niti me interesuje da to učim, s druge strane Perl-kompatibilni regexi su mi savršeno logični. regex je možda par puta sporiji od globbinga, ali na svim mašinama novijim od 286ice to se ne bi trebalo primijetiti.
O “imaginarnim problemima” reći ću samo da u tom prvom kodu praviš istu grešku jer će sad on raditi samo za slučajeve kada imaš tačno dvije tačke između prefixa i ekstenzije. Nikako da uvidiš problemsku logiku a to je da:
prefix ne sadrži tačke
naziv epizode može sadržavati bilo šta
ekstenzija je fiksna
regex ti omogućuje da napišeš kod koji tačno odražava ovo gore nabrojano, dok ćeš ti uporno pokušavati čekićem koji se zove bash zakucati sve što liči na ekser zato što ti tvoja religija ne dozvoljava da naučiš jedan jednostavan i moćan alat i poslije se čuditi neočekivanim rezultatima.
Btw no comment na “promijenio si osnovne postavke” pročitaj ponovo:
[quote]Edit:
P.S. prvobitno rješenje je pisano za konkretan problem, čovjek se već izjasnio da radi, šta pokušavaš dokazati? :-D[/quote]
A ja sam samo napisao jedno alternativno rješenje za isti problem koje isto tako radi, šta ti pokušavaš dokazati???
[quote]O “imaginarnim problemima” reći ću samo da u tom prvom kodu praviš istu grešku jer će sad on raditi samo za slučajeve kada imaš tačno dvije tačke između prefixa i ekstenzije. Nikako da uvidiš problemsku logiku a to je da:
prefix ne sadrži tačke
naziv epizode može sadržavati bilo šta
ekstenzija je fiksna[/quote]
OK, napiši regex za:
srt datoteka ima N tačaka: A.B.C.D.E.F.srt
avi datoteka je nekada a) A.B.C.avi a nekada b) A.B.C.D.avi
I sa jednim i sa drugim pristupom posebno se trebaju obraditi a) i b);
Efektivno, ti se žališ da se moje rješenje za a) ne može iskoristiti za b). Ja nisam ni rekao da može bez prepravki, samo sam napravio korekciju da % radi matching sa desne strane (=> broj tačaka u srt je beznačajan, moramo se prilagoditi broju tačaka u avi datoteci)
Btw, vjerujem da postoji jedinstven regex koji rješava i a) i b); no ne želim to gledat na pun stomak.
Malo je forum nezgodan za ovakvih diskusija, više liči na igru gluhih telefona, sad kontam šta ti želiš reći, a nadam se i obrnuto.
P.S.
Borba do smrti Vedran <=> Adis sutra kode Reshe.
P.P.S.
ja volim ove tehničke “prepirke”, to ne znači da je posrijedi lični sukob (ili možda znači? posjetite! nas! na! redovnom! sastanku!, kod Reshe, četvrtkom u 20:00)
for f in os.listdir("."):
if f.endswith(’.avi’):
avi.append(f)
if f.endswith(’.srt’):
srt.append(f)
for a in avi:
for s in srt:
if s.startswith(a[:-4]):
os.rename(a, s[:-4] + ‘.avi’)
srt.remove(s)
continue[/code]
Napravimo liste avi i srt datoteka, za svaku avi datoteku probamo naći srt datoteku sa istim početkom, ako nađemo preimenujemo avi datoteku i izbacimo srt sa liste. Mada mislim da je python jednostavniji nego ovaj opis “svojim riječima”
Dir.glob(".avi").each { |iz|
u = Dir.glob("#{iz[0…-5]}.srt").first[0…-5] + ".avi"
File.rename(iz,u)
}[/code]
Edit: zamijenio [0] sa .first da bude citljivije
to se koristi kod funkcija koje primaju blok koda kao parametar -
one u ono izmedju || stavljaju neku vrijednost
(unutar takve jedne funkcije pozoves funkciju “yield neka_vrijednost” i onda se blok pokrece po jednom sa svakom vrijednoscu za koju je yield pozvan) …
Moguce je staviti i vise vrijednosti u jednom pokretanju bloka …
Dakle each stavlja u |iz| po jedan elemenat niza i pokrece predani blok za svaki od njih …
Mada mislim da je python jednostavniji nego ovaj opis “svojim riječima”
Mogao si koristiti os.walk(); poprilicno simplificira stvari. Npr:
[code]import os
def myrename(dir, suff_old, suff_new):
for root, dirs, files in os.walk(dir):
if not len(dirs):
break
for f in files:
if f.endswith(“.txt”):
new_file = f[:-4] + suff_new
os.rename(dir + “/” + f, dir + “/” + new_file)
Sanele gdje koristiš stuff_old u myrename()? Nisam imao vremena probati, ali mislim da ne radi?! Nije riječ o pukom mijenjanju ekstenzija datoteka.
“Glob” rješenja mi se ne sviđaju, jer se može desiti da dobijamo matcheve za već preimenovane avi datoteke.
(u mom primjeru to izbjegavamo sa onim zadnjim ‘continue’)
Evo “skinuto” par linija, imal ko ideju kako izbjeći ove dvije ugnijezđene for petlje?
[code]import os
list = os.listdir(".");
srt = [f for f in list if f.endswith(’.srt’)]
avi = [f for f in list if f.endswith(’.avi’)]
for a in avi:
for s in srt:
if s.startswith(a[:-4]):
os.rename(a, s[:-4] + ‘.avi’)
srt.remove(s)
continue[/code]