Prejmenovani vsech souboru s ruzne velkymi pismeny na soubory s malymi pismeny?

Pavel Kankovsky peak na argo.troja.mff.cuni.cz
Středa Leden 8 00:50:40 CET 2003


On 7 Jan 2003, Petr Stehlik wrote:

> find ./ -name "*[A-Z]*" -maxdepth $DEPTH -exec rename2lower "{}" \;

Spravna funkce tohoto zavisi na tom, jak interaguje find (getdents(),
chdir()) a mv (rename()). Jsou zde totiz dva mozne problemy:

1. jestlize dojde k prejmenovani adresare, nemusi byt find schopen
   do toho adresare vlezt a prozkoumat jeho obsah

2. prejmenovani muze zmenit poradi polozek v adresari a muze dojit
   k tomu, ze nektere polozky nebudou prohledany nebo budou prohledany
   vicekrat

Jednodussi problem je c. 2: je to sice otazka implementace konkretniho fs,
ale asi zadna rozumna nema tu vlastnost, ze by getdents() kvuli rename()
neco vynechalo a pripadne opakovani tady moc nevadi. U klasicky
implementovanych adresaru pak navic v pripade, ze nedojde ke zmene delky
nazvu souboru ani nehrozi, ze by k te inzerovane zmene poradi vubec doslo.

Slozitejsi je problem c. 1: ono to totiz skutecne nefunguje, pokud to
najde adresar obsahujici velke pismeno -- find na nej spusti rename2lower,
ten ho prejmenuje a find ho pak nenajde, aby do nej vlezl. Resenim je
pouzit prohledavani do hloubky (-depth), pricemz se ale bude vzdy na mala 
pismena prevadet jen posledni komponenta zadane cesty.

Mimochodem, ja bych to jako fanda Titaniku udelal takto:

find -depth -print0 | perl -ln0e '
  ($d, $f) = m{^(.*/)?([^/]+)$};
  ($nf = $f) =~ tr/A-Z/a-z/;
  next if ($f eq $nf);
  rename("$d$f", "$d$nf");
'

> rename2lower je samostatny skript, pac jsem neumel poradne predavat
> parametry (ja vim, dneska byste me urcite utloukli s -print0):
> 
> mv "$*" "`echo $* | awk '{print tolower($0)}'`"

Tady bych spis vytknul to $*, specialne jeho pouziti bez uvozovek
v echo $*.


--Pavel Kankovsky aka Peak  [ Boycott Microsoft--http://www.vcnet.com/bms ]
"Resistance is futile. Open your source code and prepare for assimilation."



Další informace o konferenci Linux