Sida 1 av 1

Numrera om bildsekvens.

Postat: 23 nov 2008, 21:37
av rylleman
Jag har lite olika bildsekvenser jag vill numrera om.
Nu är de numrerade med olika startnummer och jag vill att de alla börjar med 0001.
De har alla olika namn fram till numreringen och kan även ha olika filändelser.
Ex.;
bildsekvensA_0004.png - bildsekvensA_0027.png, sekvensB_0045.jpg - sekvensB_0327.jpg osv.

Jag har kikat på rename och mv me ninte lyckats få till vad jag vill.
Jag kan döpa om sekvenserna så här i ett GUI-program, GPrename, men vill nu kunna göra det från ett bash-script.

Re: Numrera om bildsekvens.

Postat: 23 nov 2008, 21:58
av Lars
Jag vet inte om jag förstod exakt hur du vill ha det, men något sådant här kanske:

Kod: Markera allt

for f in *.jpg; do mv $f ${f/bildsekvensA/sekvensB}; done
Det ersätter alltså alla förekomster av "bildsekvensA" i variabeln $f med strängen "sekvensB".

Re: Numrera om bildsekvens.

Postat: 23 nov 2008, 22:29
av Konservburk
Om jag tolkar dig rätt så vill du döpa om bilderna så här:

bildsekvensA_0004.png - bildsekvensA_0027.png --> bildsekvensA_0001.png - bildsekvensA_0024.png
sekvensB_0045.jpg - sekvensB_0327.jpg --> sekvensB_0001.jpg - sekvensB_0283.jpg

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 01:03
av rylleman
Konservburk skrev:Om jag tolkar dig rätt så vill du döpa om bilderna så här:

bildsekvensA_0004.png - bildsekvensA_0027.png --> bildsekvensA_0001.png - bildsekvensA_0024.png
sekvensB_0045.jpg - sekvensB_0327.jpg --> sekvensB_0001.jpg - sekvensB_0283.jpg
Precis så, jag var inte tydligt nog.
Hur gör jag?

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 02:24
av David Andersson
Så här kan du använda rename. Jag skriver prename i stället för rename för att vara säker på att rätt program startas. Det är normalt samma program. Rename är bara så generiskt.

Dessa två kommandon minskar fyrsiffriga nummer i filnamnen med 3 resp 44.

Kod: Markera allt

prename -n 's/(\d\d\d\d)/sprintf("%04d",$1-3)/e' bildsekvensA*.*
prename -n 's/(\d\d\d\d)/sprintf("%04d",$1-44)/e' sekvensB*.*
Flaggan -n gör att programmet inte ändrar några filnamn, utan bara visar vilka vilka ändringar den skulle ha gjort. Om det ser bra ut, kör kommandona igen utan -n.

(Om du får för dig att öka nummer i filnamn med samma teknik, tänk på att när det är flera filer så kan den komma att försöka skriva över senare filer medans den renamar tidigare filer. (Det är inte så farligt för prename kommer att vägra skriva över filer.) De måste processas i omvänd nummerordning.)

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 10:45
av rylleman
David Andersson skrev:...
Dessa två kommandon minskar fyrsiffriga nummer i filnamnen med 3 resp 44.
...
Tack.
Men jag skulle vilja ha den här biten automatiskt så att jag inte själv behöver ange hur mycket varje sekvens ska ändras. Jag håller på med ett batch-script där omdöpningen ingår och det blir då opraktiskt att ändra värdet manuellt.

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 20:33
av David Andersson
rylleman skrev:
David Andersson skrev:...
Dessa två kommandon minskar fyrsiffriga nummer i filnamnen med 3 resp 44.
...
Tack.
Men jag skulle vilja ha den här biten automatiskt så att jag inte själv behöver ange hur mycket varje sekvens ska ändras.
Alltså ett sätt att hitta det lägsta numret, subtrahera 1, och stoppa in det nummret efter minustecknet i kommandot. Hmm.

Att hitta lägsta numret kan göras med
ls bildsekvensA_*.* | perl -ne 'print $1,"\n" if /(\d\d\d\d)/' | sort -n | head -1
eller
ls bildsekvensA_*.* | grep -o '[0-9][0-9][0-9][0-9]' | sort -n | head -1
eller
ls bildsekvensA_*.* | perl -ne '$x=$1 if /(\d\d\d\d)/ and $1<$x or not $x; END{print $x,"\n"}'
eller bara
ls bildsekvensA_*.* | head -1 | grep -o '[0-9][0-9][0-9][0-9]'

Att ta reda på vilken man ska välja tar mycket tid eftersom man måste fundera på vilket beteende man vill ha om det inte finns några filer, och vilket alternativ som är mest läsbart och underhållande. När du har funderat klart så kan du spara det minsta talet i en shell-variabel:

minsta=$(<ett av ovanstående uttryck>)

och sedan använda variabeln i prename-kommandot

prename 's/(\d\d\d\d)/sprintf("%04d",$1-'$minsta'+1)/e' bildsekvensA*.*

(Förklaring: hela perl-uttrycket skrivs inom enkelfnutt ('...') och alla dollar där tillhör perl. Men vi vill hämta värdet $minsta från shell och använda i perl-uttrycket. Därför skrivs ' före och efter $minsta för att avsluta perl-uttrycket (bara en sträng för shell) och komma åt shell-variabeln. Det går att flika in $minsta på andra sätt, men kan inte komma på korta förklaringar för dem.)

(Kan filerna börja på många andra sätt än "bildsekvensA" och "sekvensB" så det måste vara variabler också?)

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 20:45
av Konservburk
Personligen skulle jag inte leta efter det lägsta numret, utan istället använda en räknare som börjar med 1 eftersom man då även täpper till eventuella hål i sekvensen, t.ex.

bild_0005.jpg, bild_0006.jpg, bild_0008.jpg --> bild_0001.jpg, bild_0002.jpg, bild_0003.jpg

Självklart ska räknaren återställas för varje nytt unikt prefix.

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 22:43
av rylleman
Konservburk skrev:Personligen skulle jag inte leta efter det lägsta numret, utan istället använda en räknare som börjar med 1 eftersom man då även täpper till eventuella hål i sekvensen, t.ex.

bild_0005.jpg, bild_0006.jpg, bild_0008.jpg --> bild_0001.jpg, bild_0002.jpg, bild_0003.jpg

Självklart ska räknaren återställas för varje nytt unikt prefix.
Så skulle jag också föredra det hela.
Filnamnet innan numreringen skiljer mellan olika sekvenser.

Den här raden har jag fått på ett annat forum och den fungerar ganska bra, men jag tappar filändelserna.;
i=1; for x in *; do mv $x ${x%_*}_$(printf "%06d" $i); i=$(($i + 1)); done

Re: Numrera om bildsekvens.

Postat: 24 nov 2008, 23:13
av Konservburk
rylleman skrev:i=1; for x in *; do mv $x ${x%_*}_$(printf "%06d" $i); i=$(($i + 1)); done
Den återställer inte heller räknaren när det blir ett nytt prefix.

Kod: Markera allt

 (
   for f in *
   do test "x$x" = "x${f%_*}" && x="${f%_*}" && ((i++)) || i=1
      mv "$f" "${f%_*}"_$(printf '%04d' $i)."${f##*.}"
   done
)

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 00:38
av rylleman
Konservburk skrev:

Kod: Markera allt

 (
   for f in *
   do test "x$x" = "x${f%_*}" && x="${f%_*}" && ((i++)) || i=1
      mv "$f" "${f%_*}"_$(printf '%04d' $i)."${f##*.}"
   done
)
DIn kod återställde vissrligen mätaren så varje nytt prefix började om från 1 men den döpte om varenda bild i sekvenserna till *_0001.png så de skrev över varandra och det bara fanns den sista bilden i varje sekvens kvar när scriptet var kört...
Men vi närmar oss.

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 00:46
av Konservburk
rylleman skrev:DIn kod återställde vissrligen mätaren så varje nytt prefix började om från 1 men den döpte om varenda bild i sekvenserna till *_0001.png så de skrev över varandra och det bara fanns den sista bilden i varje sekvens kvar när scriptet var kört...
Men vi närmar oss.
Det gjorde den visst :-[

Så kan det gå när man sätter variabler på fel ställe. Vi försöker en gång till:

Kod: Markera allt

(
   for f in *
   do test "x$x" = "x${f%_*}" && ((i++)) || i=1
      mv "$f" "${f%_*}"_$(printf '%04d' $i)."${f##*.}"
      x="${f%_*}"
   done
)

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 01:31
av rylleman
Tack!
Nu funkar det precis som jag vill ha det!

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 03:00
av David Andersson
Jättebra att det funkar. Men det är viktigare att det är snyggt :)

1) Koden ovan förutsätter att filnamnen har ett underscore aldeles före numret och inga underscore nånstans efter numret. Den förutsätter också att det inte finns några tecken efter numret, bara extension. Man skulle kunna dokumentera förutsättningarna, men det är nog enklare att inte förutsätta nåt: Ändra bara fyra siffror och behåll allt annat i filnamnet.

2) Lägg till flaggan -i på mv så den inte skriver över filer (utan att fråga) ifall det skulle finnas kvar nån bug nånstans.

3) Introducera långa fina variabelnamn.

Uppdaterat kod:

Kod: Markera allt

(
  for f in *
  do
    currprefix=${f%[0-9][0-9][0-9][0-9]*}
    test "x$prevprefix" = "x$currprefix" && ((i++)) || i=1
    mv -i "$f" "${f/[0-9][0-9][0-9][0-9]/$(printf %04d $i)}"
    prevprefix=$currprefix
  done
)
(Är extension för unix-slang? Filnamnsuffix?)

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 07:22
av Konservburk
David Andersson skrev:Jättebra att det funkar. Men det är viktigare att det är snyggt :)
Finkod ;D

Då vill man kanske till och med ha något test för att unvika eventuella problem med
mv -i fil_0001.png fil_0001.png och liknande.

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 10:47
av rylleman
David Andersson skrev:Jättebra att det funkar. Men det är viktigare att det är snyggt :)
...
Tack för den putsningen.
Konservburk skrev:...Då vill man kanske till och med ha något test för att unvika eventuella problem med
mv -i fil_0001.png fil_0001.png och liknande.
Man kan ju alltid idiotsäkra men såhär långt behöver man inte dra det tycker jag. Ligger det redan en annan sekvens med samma namn som börjar på 0001 så kan den gott skrivas över.

Re: Numrera om bildsekvens.

Postat: 25 nov 2008, 20:57
av Konservburk
rylleman skrev:
Konservburk skrev:...Då vill man kanske till och med ha något test för att unvika eventuella problem med
mv -i fil_0001.png fil_0001.png och liknande.
Man kan ju alltid idiotsäkra men såhär långt behöver man inte dra det tycker jag. Ligger det redan en annan sekvens med samma namn som börjar på 0001 så kan den gott skrivas över.
Logiska kullerbyttor? En annan sekvens med samma namn är ju samma sekvens. ;)

Nu pratar vi om finkod. Det som kan hända är att det finns en sekvens som redan börjar med 0001, t.ex:

fil_0001.png, fil_0003.png, fil_0004.png

Då försöker skriptet byta namn på fil_0001.png till just fil_0001.png, vilket inte är tillåtet, och därför kommer mv ge ifrån sig ett felmeddelande.

Re: Numrera om bildsekvens.

Postat: 26 nov 2008, 01:19
av rylleman
Konservburk skrev:...
Nu pratar vi om finkod. Det som kan hända är att det finns en sekvens som redan börjar med 0001, t.ex:

fil_0001.png, fil_0003.png, fil_0004.png

Då försöker skriptet byta namn på fil_0001.png till just fil_0001.png, vilket inte är tillåtet, och därför kommer mv ge ifrån sig ett felmeddelande.
Jaha, du menar så. Det kan vara bra att ha när jag ska stoppa in koden i mitt script. Där kan det mycket väl hända att sekvensen redan börjar på 1.

Re: Numrera om bildsekvens.

Postat: 08 dec 2008, 22:01
av rylleman
Jag försöker lägga in kodbiten i ett nautilus-script vilket inte vill sig alls.
Skriptet fastnar på mv-raden (har lagt en echo som skickas till zenity mellan varje kodrad).
Kör jag koden genom att klistra in den i terminalen fungerar den som den skall.
Varför vill den inte köra från ett nautilus-skript?