Portál AbcLinuxu, 6. května 2025 20:14

Užitečné skripty 7: hromadné přejmenování souborů

27.11.2007 20:31 | Přečteno: 7977× | Linux | poslední úprava: 4.12.2007 19:31

Jsou lidé, kteří si myslí, že do názvu souborů nepatří smetí v podobě dikaritiky či jiných speciálních znaků. Pokud se jim na disku vyskytne nějaký šílený název, hned ho přejmenují. V tomto příspěvku ukážu skript, který práci zjednoduší.

Abstrakt

K napsání tohoto zápisku mám dva důvody:

  1. Kontaktoval mě člověk, kterému se líbil můj skript na přejmenování souborů, který jsem uveřejnil kdysi v diskusi a požádal mne o pomoc při řešení problému, se kterým si nevěděl rady. Nakonec jsme to vyřešili.
  2. Zakončím sérii užitečných skriptů. Nebýt výše uvedeného impulsu, už by mě nenapadlo nic, o čem psát. Toto je tedy poslední díl užitečných skriptů.

V dnešní moderní době by se zdálo, že pro počítače není problém pracovat s krkolomnými názvy souborů a není důvod se v pojmenování souborů nijak krotit. Přesto se najdou důvody, proč naopak používat jenom "slušná" pojmenování. Napadají mě tyto:

  1. Člověk si na to zvykl.
  2. Některé aplikace mají problémy se (některými) zvláštními znaky v názvu.
  3. Přenositelnost mezi různými počítači a systémy - ne každý chce při připojeni experimentovat s volbami mount. V horším případě - na Windows - si nemá s čím hrát a bezmocně kouká na své soubory, které mu nic nechce načíst. Windowsy se totiž nechají rozhodit i relativně neškodnými znaky, se kterými Linux nemá problémy (ale možná je to jenom chyba TotalCommanderu, nezkoumal jsem to podrobně).

Samotný skript

Před psaním tohoto zápisku jsem skript trochu upravil (aby mu bylo rozumět), takže je možné, že se vyskytla chybka. V takovém případě prosím za prominutí (a upozornění na chybu). Skript by měl udělat zhruba toto: odstranit diakritiku, písmena změnit na malá, nepohodlné znaky nahradit podtržítkem. Poté se ještě vyhodí nepotřebné znaky '_' a '-' kolem teček, více znaků '_' nebo '-' nahradí jenom jedním a sekvence '-' a '_' se nahradí jenom jednou pomlčkou.

Soubor vycisti.py
#!/usr/bin/python
# -*- coding:  utf-8

'''Přejmenuje všechny soubory a adresáře v aktuálním adresáři tak,
   aby to mělo nějakou kulturu. Rekurzivně pracuje i ve vnořených
    adresářích. 
    Výsledkem by měl být název, kde jsou jenom písmena, podtržítka,
    číslice, tečky a pomlčky (ale ne na začátku).
    Na standardní výstup píše, co přesně dělá
    Použití: vycisti.py [ > logfile ]
'''

import re
import os
import sys
import unicodedata

class FilesRenamer:
    def __init__(self, charset = None):
        if charset:
            self.locale = charset
        else:
            if os.environ.get('OS','') == 'Windows_NT':
                self.locale = "cp1250"
            else: #probably linux
                local = os.environ.get('LANG', '')
                if '.' in local: # someting like cs_CZ.UTF-8
                    self.locale = local.split('.')[1]
                else:
                    self.locale='UTF-8'
        self.initRegExps()
        self.initActionCodes()

    def log(self, code, dir, oldName, newName = '', message = ''):
        if newName:
            if message:
                print "%s: %s/%s -> %s, %s" % (self.actions[code], dir, oldName, newName, message)
            else:
                print "%s: %s/%s -> %s" % (self.actions[code], dir, oldName, newName)
        elif message:
            print "%s: %s/%s , %s" % (self.actions[code], dir, oldName, message)
        else:
            print "%s: %s/%s " % (self.actions[code], dir, oldName)

    def initRegExps(self):
        self.re_beginning = re.compile(r"^[-_]+")
        self.re_invalid_stuff = re.compile(r"[^a-zA-Z0-9_\.-]+")
        self.re_underscores = re.compile(r"_+")
        self.re_unders_dashes = re.compile(r"[_-]*-[_-]*")
        self.re_rubish_round_dot = re.compile(r"[_-]*\.[_]*")
        self.re_valid_name = re.compile(r"^[a-z0-9_\.][a-z0-9_\.-]*$")

    def initActionCodes(self):
        self.actions = {
            'ok': 'OK',
            'mv': 'Renaming',
            'ro': 'Readonly directory',
            'nr': 'Cannot rename',
            'w'  : 'Warning',
        }

    def cleanString(self, what):
        '''Gets rid of letters which are not in English alphabet'''
        assert type(what) == unicode
        normalized = unicodedata.normalize('NFKD', what)
        output = ''
        for c in normalized:
            if not unicodedata.combining(c):
                output += c
        return output

    def cleanName(self, fileName):
        '''Convert the givne string into a form which is suitable for a file name'''
        assert type(fileName) == str
        fileName = fileName.decode(self.locale) #convert to unicode
        fileName = fileName.strip() #remove spaces on the beginning and the end
        fileName = self.cleanString(fileName) #remove accents
        fileName = fileName.lower() #lower case
        fileName = self.re_invalid_stuff.sub("_", fileName) #replace invalid stuff by '_',
        fileName = self.re_unders_dashes.sub("-", fileName) #replace combination of '-' and '_' by '-'
        fileName = self.re_underscores.sub("_", fileName) #squeeze continuous underscores to one _
        fileName = self.re_beginning.sub("", fileName) #delete underscores and dashes at the beginning
        fileName = self.re_rubish_round_dot.sub(".", fileName) #removes rubbish round the dot
        return fileName.encode(self.locale)

    def renameFile(self, dir, fileName):
        '''Public: Renames the file fileName in the directory'''
        assert type(fileName) == str
        assert type(dir) == str
        try:
            new = self.cleanName(fileName)
        except:
            self.log('nr', dir, fileName, message = sys.exc_info()[0] )
            return
        if not self.re_valid_name.match(new):
            self.log('w', dir, fileName, new, "Still not valid name")
        
        if new == "":
            self.log('nr', dir, fileName, message = 'New file name is an empty string.' )
            return
        elif ( new == fileName):
            self.log('ok', dir, fileName )
            return
        else:
            self.log('mv', dir, fileName, new )
            os.rename(os.path.join(dir, fileName), os.path.join(dir, new) )
            return

    def process_dir(self, dir):
        """process all files in the folder"""
        assert type(dir) == str
        for f in os.listdir(dir):
            fileName = os.path.join(dir, f)
            if os.path.isdir(fileName): #if it is a directory
                if not os.access(fileName, os.W_OK):
                    self.log('ro', dir, fileName)
                else:
                    self.process_dir(fileName) #process the elements in the directory
                    self.renameFile(dir, f) #rename the directory itself
            else:
                self.renameFile(dir, f) #if it is a file
        return

if __name__=='__main__':
    from optparse import OptionParser
    parser = OptionParser()

    parser.add_option(
        "-c", "--charset",
        dest="charset",
        default = None,
        help = """Charset from your locale.  If it is not specified, it tries to guess it from environment."""
    )

    parser.add_option(
        "-d", "--directory",
        dest="dir",
        default = ".",
        help = "Directory, where to start. Default: '.'"
    )

    parser.add_option(
        "-u", "--unittest",
        dest="tests",
        default = False,
        action = "store_true",
        help = "Run unittests."
    )

    (options, args) = parser.parse_args()

    if options.tests:
        print "Running unittests:"
        renamer = FilesRenamer(charset = 'UTF-8')
        
        def cmp(expected, real):
            print '.',
            try:
                assert expected == real
            except:
                print "Error - strings differ:"
                print "Old: ", expected
                print "New: ", real
        
        def cmp1(renamer, oldName, newName):
            cmp(renamer.cleanString(oldName), newName)
                
            
        def cmp2(renamer, oldName, newName):
            cmp(renamer.cleanName(oldName), newName)

        cmp1(renamer, u'ůěščřžýáíé', u'uescrzyaie') 
        cmp1(renamer, u'úďťňó', u'udtno') 
        cmp1(renamer, u'ĚŠČŘŽÝÁÍÉ', u'ESCRZYAIE') 
        cmp1(renamer, u'ÚĎŤŇÓ', u'UDTNO') 
        print ''
        
        cmp2(renamer,  'ÚĎŤŇÓ.txt', 'udtno.txt')
        cmp2(renamer,  'ABC.txt', 'abc.txt')
        cmp2(renamer,  'abc ( def ).txt', 'abc_def.txt')
        cmp2(renamer,  'abc -  def . txt', 'abc-def.txt')
        cmp2(renamer,  'abc - !!!! - def . txt', 'abc-def.txt')
        cmp2(renamer,  ' abc -  def . txt ', 'abc-def.txt')
        print ''
        print "Done"
    
    else:
        if options.charset:
            renamer = FilesRenamer(charset = options.charset)
        else:
            renamer = FilesRenamer()
        renamer.process_dir(options.dir)

Lehké vysvětlení:

Možné problémy

Zaznamenal jsem problémy dvojího druhu:
  1. Na některých obzvlášť hnusných vstupech vyhodí funkce cleanName výjimku (možná to je už v cleanString, nemám to už na čem zjistit). Takový soubor se asi musí přejmenovat ručně.
  2. Na souborovém systému FAT (kde jsou chyby, tam je i Micro$oft) se nějak divně rozlišují malá a velká písmena. Výsledek je ten, že pokud se starý a nový název souboru liší jen ve velikosti písmen, soubor se nepřejmenuje, ale nevylítne chyba.Problém se dá obejít tak, že místo přímého přejmenování se soubor přejmenuje nadvakrát: Ve funkci renameFile je tedy potřeba změnit předposlední řádek
    os.rename(os.path.join(dir, fileName), os.path.join(dir, new) )
    
    na něco ve smyslu
    os.rename(os.path.join(dir, fileName), os.path.join(dir, 'tmp') )
    os.rename(os.path.join(dir, 'tmp'), os.path.join(dir, new) )
    

Místa k vylepšení, otázky

  1. Pokud si myslíte, že v unittestu chybí nějaký vypečený případ, dejte ho do diskuse.
  2. Mohl by někdo popsat, jak je to vlastně s velikostí písmen na FAT? Umí třeba poznat i znaky s diakritikou? Proč má takový problém změnit velikost písmen?

Opravy chyb

Po zveřejnění jsem našel ve skriptu chybu, takže tady je seznam (třeba jich bude i víc):
  1. 30. 11. 2007 - Na řádku if not os.access(fileName, os.W_OK): chybělo not, přidáno. (Lepší by bylo prohodit obsah větví if a else, ale takhle je to míň přepisování.)
  2. 4. 12. 2007 - Na konci skriptu bylo zmaštené předávání options.charset, opraveno (celá větev )else, asi 5 řádků).
       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

27.11.2007 20:42 helb
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Pěkné. Něco podobného umí detox.
Ilfirin avatar 27.11.2007 21:06 Ilfirin | skóre: 32 | blog: ilfblog | Liberec
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Já moc nesouhlasím s důvody, s unicodem totiž již dávno padly, ale to neubírá mě kládné hodnocení za pěkný a pro někoho velmi přínosný skript.
xxx avatar 27.11.2007 21:24 xxx | skóre: 42 | blog: Na Kafíčko
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
No jo, ale escapovat mezery v bashi je tak trochu opruz.
Please rise for the Futurama theme song.
Ilfirin avatar 27.11.2007 22:02 Ilfirin | skóre: 32 | blog: ilfblog | Liberec
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
tak to jo.

PS.: automatické doplňování nezabírá?
xxx avatar 27.11.2007 22:17 xxx | skóre: 42 | blog: Na Kafíčko
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
$touch Ahoj\ svete.. Nebo pokud mas v adresar soubory "a", "a a", "a b". Pri doplnovani se doplni pouze na a. Mezeru je opet treba zadat escapovane. Zkuste si to je to dobre videt. Proste mezera je v cli peknej opruz.
Please rise for the Futurama theme song.
Ilfirin avatar 27.11.2007 22:19 Ilfirin | skóre: 32 | blog: ilfblog | Liberec
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Tak toto mě nenapadlo. Máte pravdu.
27.11.2007 22:52 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Na to je dobry pouzivat uvozovky nebo apostrofy:-) ls -l "a[SPACE][TAB] pak doplni zbytek spravne bez "\"
xxx avatar 28.11.2007 14:08 xxx | skóre: 42 | blog: Na Kafíčko
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
O uvozovkach vim, ale jak mam vedet, ze se mi v souboru objevi mezera. Jo a na napsani uvozoovek potrebuji pridrzet SHIFT. :-)
Please rise for the Futurama theme song.
29.11.2007 16:13 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
> Já moc nesouhlasím s důvody, s unicodem totiž již dávno padly

Prave naopak, s unicodem se tyto duvody zmnohonasobily. U jinych kodovani vetsinou platilo, ze skoro vsechny znaky, ktere vidis, jsi schopen rozlisit a take snadno schopnen zadat z klavesnice. Oproti tomu mnoho znaku v unicode na prvni pohled nerozlisis, velkou cast nejsi schopen zadat a takova zero-width-space na zacatku jmena souboru muze byt opravdu lahudka pro zadavani z commandline :–).
27.11.2007 22:13 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Predem rikam, ze jsme v Pythonu jeste nic moc neplodil, ikdyz uz se na to dlouho chystam. Obcas se s nejakym pythonem setkam a v celku me prekvapujou nic nerikajici vyjimky, coz mi pripada na objektovej jazyk docela uchylny. Z prvni vety vam asi vyplyne, ze k pythonu jsem zatim lasku nenasel, takze moje vytky tak moc objektivni nebudou:-)

Jeste predem trochu k FATu. FAT 8+3 pouzival standardne tusim velky pismena pri zapisu jmena na disk, jinak uzivatel nazvy zadava case-insensitive. Ve verzi vfat (delsi jmena nez 8+3) bylo mozna tusim zapisovat velka i mala pismena ve jmene souboru, ale Windows/DOS to nerozlisoval, cili "A" bylo stejny jako "a". Nevim, jak presne se chovaly programy ve Windows, ale je fakt, ze linux odmita prejmenovat soubor "A" na "a" na pripojenym vfat oddile, protoze je to proste stejny soubor, takze pokud chces opravdu delat upper-case na lower-case, musi se to resit pres temp soubor. Osobne bych ale velky pismena nechaval, aspon na linuxu mi to vyhovuje.

A jeste nez zacnu, tak ti musim Tomiku napsat, ze ses fakt dobrej, ze jsi takovouhle funkcnost napsal v pythonu a objektove. Tohle je skutecny uznani, ne ironie.

Jeste jemny rejpnuti/ironie: ted uz musis v pythonu napsat jenom vlastni OS, pod kterym bys ten svuj skript spoustel:-)

A ted vazne. Zda se mi, ze na zadani odstranit diakritiku, písmena změnit na malá, nepohodlné znaky nahradit podtržítkem. Poté se ještě vyhodí nepotřebné znaky '_' a '-' kolem teček, více znaků '_' nebo '-' nahradí jenom jedním a sekvence '-' a '_' se nahradí jenom jednou pomlčkou. jsi pouzil skutecne zbytecne silnej jazyk a napsal jsi opravdu drsnej program. Protoze vyznavam boha roury pipe, tak bych osobne na to vyuzil spis moznosti textovych a souborovych utilit, pripadne bych to napsal v perlu, asi nejak takhle (varovani pro pripadne testery-skripty jsem nezkousel, mozna budou potrebovat doladit!!!). Objekty se mi tady proste moc nezdaji. Tak jestli nekdo bude prahnout po python-free reseni, tak prosim ...
#!/bin/bash

if [ $# -eq 0 ];then
  echo "Usage: $0 directory ..."
else
  while [ $# -gt 0 ];do
    if [ -d "$1" ];then
      find "$1" -mindepth 1 -maxdepth 1 | while read name;do
        nname="$( echo "$name" | tr 'ĄąÁÂĂÄáâăäĆÇČćçčĎĐďđÉĘËĚéęëěÍÎíłľĹĺŃŇńňÓÔŐÖóôőöŔŕŘřŚŠŞśšşŤťŢţŮÚŰÜůúűüÝýŹŽŻźžżšžŠŽ' 'AaAAAAaaaaCCCcccDDddEEEEeeeeIIiiLLllLlNNnnOOOOooooRrRrSSSsssTtTtUUUUuuuuYyZZZzzztszTSZ' | tr 'A-Z' 'a-z' | tr -cs '-0-9a-z_.' '_' | tr -s '-_' '-_' | sed 's/^[-_]\+//;s/[-_]*-[-_]*/-/g;s/[-_]\+\.\/./g;s/\.[-_]\+/./g;' )"
        if [ "$name" != "$nname" ];then mv -v "$name" "$nname";fi
        find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0r "$0"
      done
      shift
    else
      echo "Directory $1 does not exist"
    fi
  done
fi
#!/usr/bin/perl

if (scalar(@ARGV)==0) {
  print "Usage: $0 directory ...\n";
} else {
  @dirs=@ARGV;
  while ($dir=shift @dirs) {
    if (-d $dir) {
      if (opendir D,"$dir") {
        @names=readdir D;
        closedir D;
        for ($i=0;$i<scalar(@names);$i++) {
          push @dirs,"$dir/$names[$i]" if (-d "$dir/$names[$i]);
          $nname=$names[$i];
          $nname=~tr/ĄąÁÂĂÄáâăäĆÇČćçčĎĐďđÉĘËĚéęëěÍÎíłľĹĺŃŇńňÓÔŐÖóôőöŔŕŘřŚŠŞśšşŤťŢţŮÚŰÜůúűüÝýŹŽŻźžż\x9D\x9A\x9E\x8D\x8A\x8E/AaAAAAaaaaCCCcccDDddEEEEeeeeIIiiLLllLlNNnnOOOOooooRrRrSSSsssTtTtUUUUuuuuYyZZZzzztszTSZ/;
          $nname=~tr/A-Z/a-z/;
          $nname=~tr/-0-9a-z_./_/cs;
          $nname=~tr/-_/-_/s;
          $nname=~s/^[-_]+//;
          $nname=~s/[-_]*-[-_]*/_/g;
          $nname=~s/[-_]+\././g;
          $nname=~s/\.[-_]+/./g;
          if ($nname ne $names[$i]) { print STDERR "Error in rename: $!\n" unless rename "$dir/$names[$i]","$dir/$nname"; }
        }
      } else {
        print STDERR "Unable to open directory $dir: $!\n";
      }
    } else {
      print STDERR "Directory $dir does not exist\n";
    }
  }
}

P.S.: Jeste ze fungujou tagy pre, znacky code fungujou nejak podivne a po prvni prazdne radce se asi sami vypnou.
xxx avatar 27.11.2007 22:21 xxx | skóre: 42 | blog: Na Kafíčko
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Jdu brecet do kouta. Myslel jsem si, ze umim v bashi :-(. Tohle bych vymyslel cely den.
Please rise for the Futurama theme song.
27.11.2007 22:49 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
No, na prehlidku bash-top-quality skriptu bych to taky neposlal - existujou urcite jeste vetsi machri:-) Jinak ale je pravda, ze spousta lidi neobjevi ty skvely moznosti linuxovych utilitek a pak jim windows cmd pripada stejne silnej jako bash+gnu nastroje. Bohuzel pravda je jina a cmd samo o sobe i s tou chabou vybavickou pseudo nastroju ve windows neumi vubec nic oproti bashi s armadou find-utils, text-utils, file-utils atd (dnes tusim uz vsechno v baliku core-utils). Spousta lidi napr pouziva grep jenom na hledani slova a vyuziti regexpu se vyhybaji, stejne tak sed je silnej nastroj na editaci text streamu. No a kouzla s rourama a sub-shellama jsou pak uz docela sileny. Ale i tak to neni vsechno a existuji dalsi magicky triky, o kterych ani ja nemam paru.

BTW: Ted jsem si vsimnul, ze to v tom bashi rozhodilo cesky znaky pro Windows, tj. šžŠŽ, puvodne to maji byt znaky s hodnotama 0x9D 0x9A 0x9E 0x8D 0x8A 0x8E, jak je uvedeno v perl skriptu, ale treba taky nevim, jak bych nacpal do bashe znaky pomoci nejaky hexa sekvence, jako napr. v perlu pomoci \x9D atd. Aha, koukam, to neni rozhozeny - ono je to asi jenom v UTF8 a tam ty znaky nemaji zadnej vyznam, tak je tam ve ctverecku pod sebou napsano "00" a "9D", "00" a "9A" atd. No, tady je videt, ze M$ zase neco podelal a misto aby pouzili ISO-8859-2, tak vymysleli nejakou ptakovinu, ktera je az na tehle sest pismen stejne s ISO, ale znaky ť, š a č jsou jiny.
27.11.2007 23:30 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
K tomu bashu: cely ten brutal riadok by siel spravit jednym sedom, a usetrit 10 procesov spustanych pre kazdy subor, co by bolo sakra poznat, pri premenovavani velkeho stromu suborov. Na druhej strane, to rekurentne volanie sa mi fakt paci a asi ho tiez zacnem pouzivat :-)
If you hold a Unix shell up to your ear, you can you hear the C.
27.11.2007 23:33 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Navyse v dostatocne novom sede nie je problem zapisovat znaky pomocou escape sekvencii ako \x9D
If you hold a Unix shell up to your ear, you can you hear the C.
28.11.2007 00:31 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
K tomu bashu: cely ten brutal riadok by siel spravit jednym sedom, a usetrit 10 procesov spustanych pre kazdy subor, co by bolo sakra poznat, pri premenovavani velkeho stromu suborov.
Jojo, to mas recht. V tomhle pohledu bude urcite ten perl i ten python privetivejsi. Jinak ten "y" (alias tr) v sedu by se pouzit uricte dal, zalezi jaky akceptuje parametry, ale pokud by umoznoval "c" (complement) a "s" (squeeze-repeats), a kdyby sed bral sekvence \x9D, tak by ten radek mohl snad vypadat nejak takhle
        nname="$( echo "$name" | sed  'y/ĄąÁÂĂÄáâăäĆÇČćçčĎĐďđÉĘËĚéęëěÍÎíłľĹĺŃŇńňÓÔŐÖóôőöŔŕŘřŚŠŞśšşŤťŢţŮÚŰÜůúűüÝýŹŽŻźžż\x9D\x9A\x9E\x8D\x8A\x8E/AaAAAAaaaaCCCcccDDddEEEEeeeeIIiiLLllLlNNnnOOOOooooRrRrSSSsssTtTtUUUUuuuuYyZZZzzztszTSZ/;y/A-Z/a-z/;y/-0-9a-z_./_/cs;y/-_/-_/s;s/^[-_]\+//;s/[-_]*-[-_]*/-/g;s/[-_]\+\.\/./g;s/\.[-_]\+/./g;' )"


Tak ted jsem to overoval a zda se, ze muj sed (GNU sed version 4.1.5) umi \x9D, ale bohuzel neumi y/// s ruznyma dylkama a navic tudiz nelze zapsat nahrazeni complement seznamu a navic y/// nebere parametry, cili selhava prikaz
y/-0-9a-z_./_/cs
"strings for `y' command are different lengths" a po smazani pak selhava i
y/-_/-_/s;
"extra characters after command". Takze na jednoduchy zmeny to y/// v sedu staci, na slozitejsi je lepsi perl nebo tr.
Na druhej strane, to rekurentne volanie sa mi fakt paci a asi ho tiez zacnem pouzivat :-)
Kazdej den se neco novyho ucime:-) A nikdy neumime vsechno:-) BTW: Nejsem si ted vedom, ze bych ho ja sam nejak casto vyuzival, ale tady mi zrovna hoodne pomohlo:-)
28.11.2007 10:33 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Ak chapem dobre partikularnu ulohu :-), tak
y/-0-9a-z_./_/cs
by slo spravit prikazom (pri ERE, ale to je jedno, je to iba kvoli nazornosti)
s/[^-0-9a-z_.]+/_/g
a
y/-_/-_/s
by slo spravit cez
s/([-_])\1*/\1/g
(BTW prikaz tr -s '-_' '-_' mi nefacha a musim pouzit tr -s -- '-_' '-_' ale moze to byt verziou tr)
If you hold a Unix shell up to your ear, you can you hear the C.
28.11.2007 13:19 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Mas recht, pred retezec '-_' je nutny napsat klasickej --, aby program vedel, ze konci prepinace a zacinaji parametry. Tohle jsou ty malickosti, co by se doladily testovanim.

Jinak mas pravdu, vsechno by se to dalo resit regexpem v sedu, ale regexpy jsou casove narocnejsi nez jednodychu "translate". Zkus si nekdy filtrovat grepem velkej soubor na obycejny slovo, nejdriv s -E 'SLOVO' a pak -F 'SLOVO' a rozdil bys mel videt. Proto na obyc nahrazeni radeji davat tr nez s.
28.11.2007 16:03 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Skusil som ten grep. Hladal som 4 pismenkove slovo v 150MB subore, 100X za sebou a priemeroval som "user" hodnotu prikazu time. Rozdiel ziadny medzi -F a -E. Stale tvrdim, ze pustit 5 trivialnych procesov je daleko drahsie ako pustit jeden sed s 10 strasnymi pravidlami.
If you hold a Unix shell up to your ear, you can you hear the C.
28.11.2007 11:02 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Ten radek v bashi je impozantni. Zvolil jsem pro tento skript Python z nekolika duvodu (nektere uz v diskusi padly): 1) nemusim si hlidat specialni znaky ve jmenech souboru (nekdy se retezes predava jako parametr funkce, predava se dal atd. Escapovani je v takovem pripade vic magie, nez programovani) 2) na zruseni dikritiky nemusim vypisovat vsechny znaky s diakritikou 3) vypada to, ze se to da lip udrzovat 4) funguje mi to i ve Windows (se standardni instalaci Pythonu) - opravdu to potrebuji.

Ten objektovy pristup je asi profesionalni deformace, ma to treba tu vyhodu, ze trida se da pouzit i z jineho zdrojaku, kdyby to nahodou nekdo chtel.
28.11.2007 13:38 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
ad 1) co tim myslis? ja taky specialni znaky nehlidam - proste to projde pipou v bashi, pripadne regexpem

ad 2) dyt je tam vypisujes:-) Ja jsem akorat nacpal kompletne vsechny, i ty nepouzivane v CJ (vetsinou totiz problem delaji prave ty cizi znaky), ale mohl bych vypsat pouze CZ. Jinak by me taky zajimalo, jak si s tim prevodem do utf poradi python, kdyz tam bude nejakej znak mimo tu prednastavenou kodovou stranku (napr. bude na woknech a nastavis cp1250 a pak pouzijes nejaky pismeno, ktery bude iso). Napr. iconv na tom spadne.
cmp1(renamer, u'ůěščřžýáíé', u'uescrzyaie') 
cmp1(renamer, u'úďťňó', u'udtno') 
cmp1(renamer, u'ĚŠČŘŽÝÁÍÉ', u'ESCRZYAIE') 
cmp1(renamer, u'ÚĎŤŇÓ', u'UDTNO') 
ad 3) hmmm, nevim, me ten bash i perl skript pripada jednodussi, zadny objekty , proste za sebou par tr a s prikazu s jednoduchou syntaxi

ad 4) hmmm, pravda, python jsem na woknech nezkousel, ale perl na woknech urcite funguje a bash taky (at uz pod celym cygwinem, nebo pouze s vybrakovanym cygwin DLL a prislusnyma balickama, nebo taky jako v projektu gnuwin32.sf.net)

Ale jeste jsem ted mrknul na tu tridu a celkove objektovej navrh a rekl bych, ze by bylo lepsi, kdybys tu tridu udelal jako podtridu tridy String (napr. UntidyFileName) a v ni definoval metodu cleanName a pak to volala jako newname=oldname.cleanName. Protoze volani renamer.cleanName(oldName) je podle me presne ta prasarna, kterou splodi clovek zvyklej na programovani s funkceme, kterej zrovna presel na nejakej jazyk s objektama. A proto se mi taky nelibi Python, protoze self.re_invalid_stuff = re.compile(r"[^a-zA-Z0-9_\.-]+") a self.re_invalid_stuff.sub("_", fileName) nepovazuju za objektovej pristup a cekal bych spis fileName.subst(r"^[-_]+","_"). Jak se to (a) zkratilo, a (b) zprehlednilo, co? Dokud proste bude jazyk kombinovat funkce a operatory s metodama, tak to nebude poradnej OO jazyk (tim samozrejme myslim i Javu, Perl a dalsi pseudo OO jazyky:-)).
29.11.2007 09:29 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
ad2: to jsou unittesty.
28.11.2007 12:21 Leoš Literák | skóre: 74 | blog: LL | Praha
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
PRE je blokovy element, CODE je na urovni B, I, jde o obycejnou formatovaci znacku se semantickym vyznamem. CODE urcite nebude resit nove radky, odstavce apod.
Zakladatel tohoto portálu. Twitter, LinkedIn, blog, StackOverflow
28.11.2007 13:39 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
OK, s tim code jsem to nevedel ... OK, priste na delsi kod jenom pre.
eXces avatar 27.11.2007 22:17 eXces | skóre: 15 | blog: i hate mondays;) | Jihlava
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Návrh na další skript:-) Adresář plný .ttf a z nich je potřeba vytvořit třeba pdf (nebo něco jiného, co by šlo vytisknout), kde bude vždy název písma a pak ukázka toho písma (prostě kousek napsanej tím písmem) a ještě nejlépe tak, aby nebylo na výsledném papíře zbytečně mnoho volného místa. Tak co, je to výzva, že?:-D
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. --Albert Einstein
27.11.2007 22:40 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Hele, nekdo na abclinuxu nebo na rootu delal nedavno tusim clanek nebo blog se seznamem ghostscript fontu a vygeneroval z toho PDFko. Bohuzel to ted nemuzu najit, snad si nekdo vzpomene presne.
Josef Kufner avatar 28.11.2007 00:05 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Já nechci být hnusný, ale ... ehm... zlatej iconv...
#!/bin/bash
# prejmenovat.sh
srcenc=latin2
while [ -n "$1" ]
do
	n="$(iconv -f "$srcenc" -t "ascii//TRANSLIT" <<< "$1" )"
	mv "$1" "$n"
	rename 's/ +/_/g;y/A-Z/a-z/' "$n"
	shift 1
done
find . -depth | xargs prejmenovat.sh
Joo, je to trošku neefektivní a ty regexpy u rename budou chtít trošku doladit, ale v zásadě by to fungovat mělo...

ps: Netestoval jsem to.
Hello world ! Segmentation fault (core dumped)
28.11.2007 00:55 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Sakra, to jsem presne hledal!! Ten "ascii//TRANSLIT":-) Blby je, ze mi iconv chcipal, pokud ve zdrojovej sade byl nejakej znak mimo definovanej. Takze kdyz budu mit mix iso a cp1250 nebo pripadne v cp1250 nejakej paznak, tak iconv chcipne. Ale jinak bych taky asi sel do iconvu.

Ten rename nevim, jestli by fungoval. Podle manu
NAME
       rename - Rename files

SYNOPSIS
       rename from to file...

DESCRIPTION
       rename will rename the specified files by replacing the first occurrence of from in their name by to.

       For example, given the files foo1, ..., foo9, foo10, ..., foo278, the commands

              rename foo foo0 foo?
              rename foo foo0 foo??

       will turn them into foo001, ..., foo009, foo010, ..., foo278.

       And
              rename .htm .html *.htm

       will fix the extension of your html files.
Takze to bude asi ciste na string-to-string konverzi, zadny regulary. Nebo mas jinou verzi? Ja mam "rename from util-linux-2.12r" (kterej manas to do CZ prelozil jako "rename na util-linux-2.12r"???) Jinak tech regexpu ti tam jeste par chybi:-)
Josef Kufner avatar 28.11.2007 19:47 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
V debianu je rename, který umí regexpy. Je to na tohle velmi mocná věc. Vpodstatě všecky scripty které tady byly bys pomocítohohle rename a hromádky regexpů nahradil. A ten iconv... to //TRANSLIT říká, že má buď najít podobný nebo ignorovat, ale moc jsem to netestoval. Pak by měl ještě fungovat //IGNORE, který blbosti prostě zahazuje. Bohužel dokumentace o tomhle celkem mlčí a nebýt API v PHP, tak o tom nevím...
Hello world ! Segmentation fault (core dumped)
28.11.2007 00:48 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Ty jo, Tomiku, zabrednul jsem na tvuj predchozi skript z dubna o stahovani z rapidshare:-) To je dobry, taky jsem si nedavno vlastni napsal, funkce prakticky stejna, akorat mam moznost vice IP adres, takze mam seznam proxy serveru a kdyz mi rapid napise "cekej 200minut", tak se pouzije jinej proxy. Pred par dny jsem taky napsal stahovac pro megauploads:-) Ten megauploads je pekne hnusnej. Odpocitavaci promenna se meni a ma podivny jmeno, napr.
document.getElementById("dlcounter").innerHTML = 'Please wait <b>'+x1786+'</b> seconds'
a URL na stahovanej soubor se tvori pomoci JS funkci, napr.
document.getElementById("download_html").innerHTML = '<a href="Array" class="downloadhtml" onclick="loadingdownload();">Click here to download</font></a>';
var a = String.fromCharCode(Math.abs(-101));
var d = '5' + String.fromCharCode(Math.sqrt(3249));
document.getElementById("dlbutton").innerHTML = '<a href="http://www41.megaupload.com/files/2a9f31' + d + a + 'afac798acff4e54a6c927d7/ANTOINE DE SAINT-EXUPÉRY - Malý Princ.pdf" onclick="loadingdownload();"><IMG SRC="" WIDTH="165" HEIGHT="39" BORDER="0" ALT="" id="dlimage" onmouseover="dlimg.src=this.src;this.src=dlimgover.src;" onmouseout="this.src=dlimg.src;"></a>';document.getElementById('dlcounter').style.display = 'none';document.getElementById('dlcounterimg').style.display = 'none';document.getElementById('dlimage').src = dlimg.src;
Takze jsem na to udelal jednoduchej JS parser a interpret:-) Zatim umi jenom funkce/metody String.fromCharCode(), Math.abs() a Math.sqrt() a operaci "+":-) Ani jsem necekal, ze to bude fungovat, ale jede to:-)

Nejsou sice uplne dokonaly, ale pro moje potreby zatim staci. Pri zmenach stranek budu muset holt upgradovat.
28.11.2007 07:14 mrw
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Jestli jsem pochopil, je toto poslední díl seriálu o skriptech. Přesto bych měl jeden problém z jiné oblasti. Posílám-li kamarádům fotky, zmenšuju je na 1024*768, 800*600, prostě tak, že to na podívání na monitoru stačí. Jenomže fotky mám už před hromadnou konverzí pootáčené a žádný z nástrojů pro hromadnou konverzi fotek, který jsem našel, neřeší můj problém. Použiju-li Picwiz, Kipi-plugini, convert z Imagemagicu, je vodorovná fotka v rozlišení např. 800x600, ale fotka na výšku je 600x800. A já bych rád, aby fotka, která je na výšku měla 450*600. Zkrátka, aby svislý rozměr v ose y měl pokaždé hodnotu např. 600. Zvlášť to vynikne v případě, že tvořím DVD-slideshow, nebo prostě vkládám fotky do videa. DVD rozlišení je 720x576. Proto potřebuju, aby obojí druh fotek, na výšku i na šířku měl ve svislém směru rozlišení 576. Teď řeším problém tak, že zmenšuju fotky zvlášť na šířku a zvlášť na výšku. Moje představa je taková, že by skript zjišťoval, která osa má větší rozlišení a podle toho by rozhodl, jaké rozlišení použije. Možná by časem neškodilo, tuto funkci implementovat do výše zmíněných grafických nástrojů. Děkuju.
28.11.2007 11:13 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Na zmensovani mam taky nejaky skript, ale nezkoumal jsem, jestli dovede zmensit na pevnou vysku, ale myslim, ze tohle by mohlo zabrat, viz man ImageMagick.
size="x576"
for i in  *.jpg *JPG
 do
  echo "$i" 
  convert -sample $size $i nahledy/$i
 done
Sam pouzivam v tomto skriptu size="800x800>", coz mi zmensi vsechny obrazky, aby vetsi rozmer nebyl pres 800px.
Josef Kufner avatar 28.11.2007 19:50 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
convert -resize tohle dělá. Prostě napíšeš rozměry obdélníku a ono to fotku zmenší tak, aby se vešla. Takže, pokud uděláš convert -resize 2000x576, tak to máš v suchu.
Hello world ! Segmentation fault (core dumped)
28.11.2007 09:07 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Mam takovej dojem (a ted jsem ten dojem overil), ze convert/mogrify z ImageMagick umi sam dopocitava druhej rozmer, takze kdyz se zada napr. -resize x600, takze ten convert to resizne vzdy na Y=600, otestovano:
pic-1.jpg JPEG 2304x1728 2304x1728+0+0 DirectClass 8-bit 902.07kb 
pic-2.jpg[1] JPEG 1728x2304 1728x2304+0+0 DirectClass 8-bit 1.20726mb 0.360u 0:02
$ convert -verbose pic-1.jpg -resize x600 pic-1-a.jpg
pic-1.jpg JPEG 2304x1728 2304x1728+0+0 DirectClass 8-bit 902.07kb 
pic-1.jpg=>pic-1-a.jpg JPEG 2304x1728=>800x600 800x600+0+0 DirectClass 16-bit 97.8203kb 0.810u 0:02
$ convert -verbose pic-2.jpg -resize x600 pic-2-a.jpg
pic-2.jpg JPEG 1728x2304 1728x2304+0+0 DirectClass 8-bit 1.20726mb 
pic-2.jpg=>pic-2-a.jpg JPEG 1728x2304=>450x600 450x600+0+0 DirectClass 16-bit 102.682kb 0.620u 0:02
Je to to, co jsi potreboval?
28.11.2007 11:09 mrw
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
To je ono, díky
28.11.2007 09:43 David Jaša | skóre: 44 | blog: Dejvův blog
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
A co se stane, když budu mít ve stejném adresáři soubory pisnicka.mp3 a písnička.mp3 ?

Jinak pro samotné zbavení se diakritiky se dá použít v příkazové řádce příkaz unaccent (1) .
oVirt | SPICE
28.11.2007 11:17 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
No ja vedel, ze jsem na neco zapomnel. Nastesti, a to si priznejme, se skript pouzije na prejmenovani mp3 a ty jsou cislovane.

Ten unaccent si prohlidnu. Nakonec treba dame dohromady i kratky bashovy skript. Jeste aby to fungovalo i ve Woknech.
28.11.2007 18:24 David Jaša | skóre: 44 | blog: Dejvův blog
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
A co když budou v jednom adresáři důležitý_dokument.odt a dulezity_dokument.odt? ;-)

unaccent asi moc integrovatelný do widlí nebude. Je to ale CLI k libunaccent, nad kterou by mohlo jít napsat nějaké jiné rozhraní šité na míru widlím nebo třeba gnome. :-)
28.11.2007 13:15 CET
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Jojo, to me napadlo, ale v puvodnich podminkach to nebylo:-) Takze opravene i pro tenhle pripad .... (plus upraveno tr -s '-_' na tr -s -- '-_' ...)
#!/bin/bash

if [ $# -eq 0 ];then
  echo "Usage: $0 directory ..."
else
  while [ $# -gt 0 ];do
    if [ -d "$1" ];then
      find "$1" -mindepth 1 -maxdepth 1 | while read name;do
        nname="$( echo "$name" | tr 'ĄąÁÂĂÄáâăäĆÇČćçčĎĐďđÉĘËĚéęëěÍÎíłľĹĺŃŇńňÓÔŐÖóôőöŔŕŘřŚŠŞśšşŤťŢţŮÚŰÜůúűüÝýŹŽŻźžżšžŠŽ' 'AaAAAAaaaaCCCcccDDddEEEEeeeeIIiiLLllLlNNnnOOOOooooRrRrSSSsssTtTtUUUUuuuuYyZZZzzztszTSZ' | tr 'A-Z' 'a-z' | tr -cs -- '-0-9a-z_.' '_' | tr -s -- '-_' '-_' | sed 's/^[-_]\+//;s/[-_]*-[-_]*/-/g;s/[-_]\+\.\/./g;s/\.[-_]\+/./g;' )"
        if [ "$name" != "$nname" ];then 
          if [ -e "$nname" ];then
            i=0
            oname="$nname"
            while [ -e "$nname" ];do nname="$( printf "%s.%05i" "$oname" $i )";i=$[$i+1];done
          fi
          mv -v "$name" "$nname"
        fi
        find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0r "$0"
      done
      shift
    else
      echo "Directory $1 does not exist"
    fi
  done
fi
#!/usr/bin/perl

if (scalar(@ARGV)==0) {
  print "Usage: $0 directory ...\n";
} else {
  @dirs=@ARGV;
  while ($dir=shift @dirs) {
    if (-d $dir) {
      if (opendir D,"$dir") {
        @names=readdir D;
        closedir D;
        for ($i=0;$i<scalar(@names);$i++) {
          push @dirs,"$dir/$names[$i]" if (-d "$dir/$names[$i]);
          $nname=$names[$i];
          $nname=~tr/ĄąÁÂĂÄáâăäĆÇČćçčĎĐďđÉĘËĚéęëěÍÎíłľĹĺŃŇńňÓÔŐÖóôőöŔŕŘřŚŠŞśšşŤťŢţŮÚŰÜůúűüÝýŹŽŻźžż\x9D\x9A\x9E\x8D\x8A\x8E/AaAAAAaaaaCCCcccDDddEEEEeeeeIIiiLLllLlNNnnOOOOooooRrRrSSSsssTtTtUUUUuuuuYyZZZzzztszTSZ/;
          $nname=~tr/A-Z/a-z/;
          $nname=~tr/-0-9a-z_./_/cs;
          $nname=~tr/-_/-_/s;
          $nname=~s/^[-_]+//;
          $nname=~s/[-_]*-[-_]*/_/g;
          $nname=~s/[-_]+\././g;
          $nname=~s/\.[-_]+/./g;
          if ($nname ne $names[$i]) {
            if (-e $nname) {
              $i=0;
              $oname=$nname;
              while (-e $nname) { $nname=sprintf("%s.%05i",$oname,$i++); }
            }
            print STDERR "Error in rename: $!\n" unless rename "$dir/$names[$i]","$dir/$nname";
          }
        }
      } else {
        print STDERR "Unable to open directory $dir: $!\n";
      }
    } else {
      print STDERR "Directory $dir does not exist\n";
    }
  }
}
28.11.2007 18:06 David Jaša | skóre: 44 | blog: Dejvův blog
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
V bashi bych použil místo tr už zmíněný unaccent a perl by snad měl umět rozložit akcentovaný znak na kombinující akcent a samotný znak a poté akcenty vyříznout.
23.6.2009 10:23 epcim
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů

Potřeboval jsem to rozjet pod winxp a cygwinem (tr nefungoval). Výsledek vypadá následovně. PS: Je tam opravena chybka viz druhé find. Filtruji .svn adresáře. Změna kalkulace i+1, původní pod bas v cygwin nefungovala. S unaccent viz dále v diskusi by to bylo asi výrazně rychlejší. IFS je asi zbytečné měnit.

 

 

#!/bin/bash

srcenc=cp1250

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

if [ $# -eq 0 ];then
  echo "Usage: $0 directory ..."
else
  while [ $# -gt 0 ];do
    if [ -d "$1" ];then
      find "$1" -mindepth 1 -maxdepth 1 -type f | grep -v ".svn" | while read name;do
        echo "INFO: Filename - $name"
        nname="$(iconv -f "$srcenc" -t "ascii//TRANSLIT" <<< "$name" )"
        nname="$(echo "$nname" | sed -e "s/'//g" )"
        if [ "$name" != "$nname" ];then
          if [ -e "$nname" ];then
            echo "WARNING: Filename already exist - $nname"
            i=0
            oname="$nname"
            while [ -e "$nname" ];do nname="$( printf "%s.%05i" "$oname" $i )";i=$(($i+1));done
          fi
          svn rename "$name" "$nname"
        fi
      done
      find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0r "$0" | sed -e "s:[-a-zA-Z0-9_/. \]*.svn ::g"
      shift
    else
      echo "Directory $1 does not exist"
    fi
  done
fi


# restore $IFS
IFS=$SAVEIFS

 

 


 

satanatas avatar 28.11.2007 10:04 satanatas | skóre: 14 | blog: vše co můžete s klidem hodit za hlavu ze světa linuxu i jiných světů | Graveyard
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
imho dnes zbytečnost, alespoň pro mně. diakrituku v názvech souborů používám snad jedině v /home/* a /srv/*, a až na pár podivností s kaffeine bez problému. i v cli.
"Smoke me a kipper, I'll be back for breakfast!" - Ace Rimmer || gentoo infected. || the city of kremathorium || ZLO
28.11.2007 10:23 David Jaša | skóre: 44 | blog: Dejvův blog
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Největší průser s diakritikou s názvech souborů je přenositelnost mezi OS. Vypálíte CD na jednom systému, vložíte do počítače s jiným a je na průšvih zaděláno. Máte-li (čitelná) CD vypálená např. na Windows 9x, zkuste je dát do počítače s linuxem nebo Windows XP a nebudete se stačit divit...
Ilfirin avatar 28.11.2007 10:31 Ilfirin | skóre: 32 | blog: ilfblog | Liberec
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Tak ale tohle má přece řešit souborový systém na CD (udf, joliet, iso 9660).
28.11.2007 18:01 David Jaša | skóre: 44 | blog: Dejvův blog
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpověděl sis za mě rovnou v námitce. ;-)
1.12.2007 00:13 dan | skóre: 9 | blog: paranoia | JO60WA
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Odpovědět | Sbalit | Link | Blokovat | Admin
Nekde asi delam chybu
Cannot rename: ./spole�ensk� 48.txt , exceptions.UnicodeDecodeError
Navic mi unika, jak dosahnout vycisteni podadresaru a jak pustit skript na jiny adresar, nez ve kterem je .py umisten.
Víra se nikdy nezrodí jako výsledek racionální argumentace
3.12.2007 14:30 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
To je presne ten vstup, o kterem jsem psal. Muzes mi poslat nejaky vypis, ze ktereho bych se dozvedel vic? Zejmena locales (v bashi: echo $LANG), jak se ten soubor dostal na disk (vytvoreny v linuxu, sitovy disk, windowsi disk ...), jak se ten nazev zobrazi treba v mc.

Podadresare to cisti automaticky. Cisti to adresar, odkud to zavolas (mam ho v ~/bin, takze nemusim psat cestu), pokud chces neco jineho, tak napis `vycisti.py -d /cesta/k/adreari`.
3.12.2007 18:39 dan | skóre: 9 | blog: paranoia | JO60WA
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Jde o debian jadro 2.6.18-5-686, locales cs_CZ.UTF-8. Soubor se na disk dostal z win mne nezname verze, pomoci WinSCP. V mc i v konzoli se zobrazi s otazniky "spole?ensk? 48.txt" Pokud to pomuze, soubor je ke stazeni zde. Zkusil jsem ho rozbalit (tar xvfz soubor.tar.gz) a nedoslo ke zmene.

Figl s ~/bin funguje. Podadresare ne, pri zpracovani zahlasi
Readonly directory: ././Smaž mne
i kdyz jsou volna prava pro vsechny. Stejne dopadne spusteni scriptu pod rootem, to uz nechapu, zrejme nebude chyba v pravech adresare.
drwxrwxrwx 2 dan dan 4,0K 2007-12-03 18:03 Smaž mne
Diky za pomoc.
Víra se nikdy nezrodí jako výsledek racionální argumentace
4.12.2007 16:55 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
pri zpracovani zahlasi
Readonly directory: ././Smaž mne
i kdyz jsou volna prava pro vsechny.
Jsi prvni, kdo tu chybu opravdu zaznamenal (vsichni diskutuji, ale nikdo si to nevyzkousi). Ja jsem ji nasel az po zverejneni clanku a uz jsem ji tam opravil. Na konci clanku jsem zalozil seznam chyb, aby slo sledovat zmeny.

Zkusim se podivat, kde vlastne pada ta konverze a co s tim, ale neslibuji, ze to bude hned.
4.12.2007 20:20 Tomáš | skóre: 31 | blog: Tomik
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Tak ten problem s UnicodeDecodeError vypada zhruba takto: Na systemu s UTF skript chce prevadet UTF do Unicode. V nazvu souboru je ale nejaky zmrseny znak (puvodne asi č), ktery do UTF nepatri. Proto spadne.

Zkousel jsem si s tim hrat a zjistil jsem, ze staci skriptu vnutit jine kodovani (cp1250) a projde to, dokonce to spravne pozna zmrsene znaky a vysledkem bude v Tvem pripade a 'spolecenska_kronika_48.txt'.

Zkus teda pustit skript takto:
vycisti.py -c cp1250
a melo by to spravne prejmenovat, mne to funguje, a to mam nejspis identicky system. Zkopiruj si stavajici verzi, predtim tam bylo vic chyb.

Obecne se da rict, ze pokud mas adresar, u ktereho jsi si jisty, ze je tam blbe (asi windows) kodovani, tak spust skript nejdriv tak, jak jsem uvedl vyse. Jsou totiz znaky, ktere se daji nejakou nahodou prevest do unicode, ale skript je nakonec zrusi a nahradi podtrzitkem (vysledek by treba mohl byt 'spole_ensk_kronika_48.txt'), takze bys pak musel jeste rucne nahrazovat podtrzitka.
5.12.2007 00:24 dan | skóre: 9 | blog: paranoia | JO60WA
Rozbalit Rozbalit vše Re: Užitečné skripty 7: hromadné přejmenování souborů
Dobra prace, uz to funguje. Ze se nenahradi vsechny pozkozene znaky optimalne nevadi. Staci, kdyz timto pominou problemy, ktere jsem pri dalsim zpracovani s poskozenymi soubory mel. Jeste jednou diky!
Víra se nikdy nezrodí jako výsledek racionální argumentace

Založit nové vláknoNahoru

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.