Bash-script för att fixa filnamn

Permalänk
Medlem

Bash-script för att fixa filnamn

Jag är inte så haj på scripting, men vill skriva ett script för bash som enligt ett reguljärt uttryck ändrar namnen på alla filer i en katalog och dess underkataloger.

I mappen /media/music/ vill jag i filnamnen ersätta mellanslag, kommatecken och andra specialtecken med underscore _ samt alla ÅÄÖåäö med aao samt ändra alla VERSALER till gemener.

Någon som har ett tips på hur det reguljära uttrycket ser ut samt på bashfilen som behövs?
Tack på förhand!

Permalänk
Medlem

Alla tecken har ju en ASCII-siffra som du kan använda i scriptet.
(a=A+32 decimalt så att säga)

Permalänk
Medlem

Jag ser en del problem med att göra ett sådans bash-script.
t.ex. om du har:
"/media/music/Britney Spears/some_random_bs_album/Britney Spears - Låttitel.ogg"
så vill du förmodligen att det ska bli:
"/media/music/britney_spears/some/random_bs_album/britney_spears-lattitel.ogg"
..och då måste du ju först skapa den mappen innan du kan flytta/byta namn på själva filen.. och jag har då ingen aning om hur man skulle kunna lyckas med det utan att typ göra någon horribelt awk-uttryck.
(Detta förutsatt att du vill att mapparna ska vara gemener osv. också..)

Ifall alla filer bara ligger i rooten /media/music, så skulle det fungera med något typ:

for filnamn in `ls -1 /media/music/`;do nyttnamn=$filnamn for replacewithunderscore in " " "&" "<random skittecken>"; do nyttnamn=$(echo "$nyttnamn" | sed s/'$replacewithunderscore'/_/) nyttnamn=$(echo "$nyttnamn"|tr 'A-Z' 'a-z')

Men jag antar att du har någon sorts mappstruktur, vilken blir ett problem. Ifall du har python installerat skulle os.walk() kunna göra hela processen väldigt smidig.

#!/usr/bin/python import os def syntax(item): #gör till gemener: nn=item.lower() #specialtecken -> underscore for uscore in (' ','__',"'",'`',"'",'^','"','¨','(',')','[',']','=', ',',':',';','*','!','@','£','#','¤','$','%','&','{','}'): nn=nn.replace(uscore,'_') # åäö->aao nn=nn.replace('å','a').replace('ä','a').replace('ö','o') return nn for root,dirs,files in os.walk('/media/music/',topdown=False): for name in files: # byt först namnet på filerna newname=os.path.join(root,syntax(name)) name=os.path.join(root,name) os.rename(name,newname) for name in dirs: # sedan på mapparna newname=os.path.join(root,syntax(name)) name=os.path.join(root,name) os.rename(name,newname)

Permalänk
Medlem

Ett stort tack! Med några smärre modifikationer fick jag _precis_ det script jag sökte! Tack igen!

Permalänk
Medlem

vad gjorde du för modifikationer då?

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av e5150
Jag ser en del problem med att göra ett sådans bash-script.
t.ex. om du har:
"/media/music/Britney Spears/some_random_bs_album/Britney Spears - Låttitel.ogg"
så vill du förmodligen att det ska bli:
"/media/music/britney_spears/some/random_bs_album/britney_spears-lattitel.ogg"
..och då måste du ju först skapa den mappen innan du kan flytta/byta namn på själva filen.. och jag har då ingen aning om hur man skulle kunna lyckas med det utan att typ göra någon horribelt awk-uttryck.
(Detta förutsatt att du vill att mapparna ska vara gemener osv. också..)

Ifall alla filer bara ligger i rooten /media/music, så skulle det fungera med något typ:

for filnamn in `ls -1 /media/music/`;do nyttnamn=$filnamn for replacewithunderscore in " " "&" "<random skittecken>"; do nyttnamn=$(echo "$nyttnamn" | sed s/'$replacewithunderscore'/_/) nyttnamn=$(echo "$nyttnamn"|tr 'A-Z' 'a-z')

Men jag antar att du har någon sorts mappstruktur, vilken blir ett problem. Ifall du har python installerat skulle os.walk() kunna göra hela processen väldigt smidig.

#!/usr/bin/python import os def syntax(item): #gör till gemener: nn=item.lower() #specialtecken -> underscore for uscore in (' ','__',"'",'`',"'",'^','"','¨','(',')','[',']','=', ',',':',';','*','!','@','£','#','¤','$','%','&','{','}'): nn=nn.replace(uscore,'_') # åäö->aao nn=nn.replace('å','a').replace('ä','a').replace('ö','o') return nn for root,dirs,files in os.walk('/media/music/',topdown=False): for name in files: # byt först namnet på filerna newname=os.path.join(root,syntax(name)) name=os.path.join(root,name) os.rename(name,newname) for name in dirs: # sedan på mapparna newname=os.path.join(root,syntax(name)) name=os.path.join(root,name) os.rename(name,newname)

Inget större problem...

find <katalog> -type f | grep '.mp3$' | while read i; do mv "$i" "$(echo $i | tr '[ ,]' '_' | tr 'A-Z' 'a-z' | tr '[ÅÄÖåäö]' '[aaoaao]')"; done

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av m0REc
Inget större problem...

find <katalog> -type f | grep '.mp3$' | while read i; do mv "$i" "$(echo $i | tr '[ ,]' '_' | tr 'A-Z' 'a-z' | tr '[ÅÄÖåäö]' '[aaoaao]')"; done

Ja, det där går ju bra, så länge alla mapparna uppfyller "namnkraven", annars blir det så här:
mv: cannot move `/tmp/TEST/aaa[aaa' to `/tmp/test/aaa_aaa': No such file or directory
..och jag kan då inte komma på något elegant sätt att ta hänsyn till det. :/

Permalänk
Medlem

Eftersom kommandot inte rör mappar ("-type f" gör att den bara hittar filer) så är det inga problem.

Men visst jag skulle nog gjort det i något perl istället.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av GunnarD
Eftersom kommandot inte rör mappar ("-type f" gör att den bara hittar filer) så är det inga problem.

Men visst jag skulle nog gjort det i något perl istället.

$ find /tmp -type f /tmp/DIRECTORY1/fil1 $ echo "/tmp/DIRECTORY1/fil1" | tr '[ ,]' '_' | tr 'A-Z' 'a-z' | tr '[ÅÄÖåäö]' '[aaoaao]' /tmp/directory1/fil1 $ mv /tmp/DIRECTORY1/fil1 /tmp/directory1/fil1 mv: cannot move `/tmp/DIRECTORY1/fil1' to `/tmp/directory1/fil1': No such file or directory

Även om `find / -type f` bara letar reda på filer, så ligger ju filerna i mappar.

Permalänk
Hedersmedlem

Oops, tänkte jag inte på.

find <katalog> -type f | grep '.mp3$' | while read i; do cd "$(dirname $i)"; file="$(basename $i)"; mv "$file" "$(echo $file | tr '[ ,]' '_' | tr 'A-Z' 'a-z' | tr '[ÅÄÖåäö]' '[aaoaao]')"; done

Något sådant...

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av m0REc
Oops, tänkte jag inte på.

find <katalog> -type f | grep '.mp3$' | while read i; do cd "$(dirname $i)"; file="$(basename $i)"; mv "$file" "$(echo $file | tr '[ ,]' '_' | tr 'A-Z' 'a-z' | tr '[ÅÄÖåäö]' '[aaoaao]')"; done

Något sådant...

...men mappnamnen blir fortfarande inte "snyggare"

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av e5150
...men mappnamnen blir fortfarande inte "snyggare"

... vilket det inte stod någonting om i första inlägget.