Multi-rename

Jesi probao uopšte?

[code]${var%Pattern}, ${var%%Pattern}

{$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 :wink:

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 :slight_smile: Sasvim je svejedno da li koristiš kobasicu ili jedan jedini znak ako ne znaš šta taj znak znači :slight_smile:

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

Ako ne vidiš vezu, onda ne znam, možda posjeta očnom? (lol, nisam mogao propustit priliku)

Radi i sa primjerom sa početka threada, i sa imaginarnim primjerom sa više tačaka.

Dodao sam output u poruku. Sjedi sad fino, uzmi čašu vode i šećera i pročitaj čitav thread od početka…

Nastavak:

[code]/home/user/tmp> for f in *.srt; do

base=${f%.*}
prefix=${base%.*}
mv "$prefix.avi" "$base.avi"

done
mv: cannot stat `Enterprise 1x03.Fight or flight.avi’: No such file or directory[/code]

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? :smiley:

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 :slight_smile: 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 :slight_smile: 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??? :stuck_out_tongue:

http://tldp.org/LDP/abs/html/parameter-substitution.html#PCTPATREF (%, %%, # i ## operatori)

[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)

Ma naravno :slight_smile:
U lijevom uglu (stola kod reshe) Adis naoružan baš-čekićem, a u desnom uglu Vedran sa regeks-kobasicom. Ko će pobijediti? stay tuned!

Evo od mene za kraj “korektno” rješenje u Pythonu.
Datoteke:

1.a.b.avi 1.a.b.c.d.srt 2.a.b.avi 2.a.b.c.d.srt 3.a.avi 3.a.b.c.d.srt 4.avi 4.x.y.z.blablabla.srt
Kod:

[code]#!/usr/bin/env python

import os

srt = []
avi = []

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” :wink:

Pa jeste, Python rješenje je ekvivalentno ali duže :smiley: nekome je od svega ovoga lakše otvoriti file manager i promijeniti imena jedno po jedno…

Moj doprinos temi …

[code]#!/usr/bin/ruby

require ‘ftools’

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

Hamo, šta mu dođe taj |iz| ?

Ja stavljam lovu na Vedrana (volim RegEx, Boze moj).
Btw. koja je kvota? :smiley:

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” :wink:

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)

myrename(“.”, “.srt”, “.avi”)[/code]
…ili jos krace koristenjem glob modula (thanx hami :)):

[code]import os, glob

lst = glob.glob(“*.srt”)
for i in lst:
new = i[:-4] + “.avi”
os.rename(i, new)[/code]

ovaj kod dole ti ne radi kako treba … :wink:
Za domacu zadacu, skontaj sta ne valja :wink:

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]