Portál AbcLinuxu, 5. listopadu 2025 10:54
IFS=` ` for i in `find . -name \*\ \*`; do mv "$i" `echo "$i" |tr ' ' _`; done
#!/bin/bash
for line in `find . -name \*\ \* | sed 's/\( \)/\\\/g' `; do
# zpracuj $line na puvodni jmeno souboru
file1=`echo $line | sed 's/\\\/\ /g' `;
# zpracuj $line na nove jmeno souboru
file2=`echo $line | sed 's/\\\/_/g' `;
mv "$file1" $file2;
done
notas:/home/cijoml/work# find . -name \*\ \* ./HP1220CD_install/Symbol_Sets/SYM readme.txt
for i in $(seq 10); do
find -mindepth $i -maxdepth $i |xargs -i rename "s/ /_/g" {}
done
depth=$(find -printf "%d\n" |sort -gr |head -n 1)
for i in $(seq $depth); do
find -mindepth $i -maxdepth $i |xargs -i rename "s/ /_/g" {}
done
#!/bin/bash
##################
function rmspc()
{
if [ $(echo "$file"| grep -c " ") -ne "0" ]; then
echo "$file --> $(echo "$file" | sed 's/\ /_/g')"
fi
}
function dir()
{
for file in *; do
if [ -d "$file" ]; then
rmspc
cd "$file"
echo "$PWD"
dir
cd ..
else
rmspc
fi
done
}
dir
Myslim ze to je "ladici" verze takze tam misto mv je echo. Slo by to urcite udelat lip, ostatne jako vsechno
Ahoj,
a co třeba tohle:
find <"kořenový" adresář> -exec rename 's/([^\ ]*)\ ([^\ ]*)/$1_$2' {} +
kde kořenovým adresářem myslím kořen podstromu vaší adresářové struktury, kterého se to má týkat. Tato ukázka počítá jen s jednou mezerou v názvu souboru.
find -depth -exec rename "s/(?!.*\/) +(?=[^ ]*)/_/g" {} \;
find -depth -exec rename 's/(?!.*\/) +(?=[^ ]*)/_/g' {} \;
BTW: Bash 3.1.17(1)-release to vezme i s uvozovkami a Bash 2.05b.0(1)-release jen s apostrofy.
perl -mFile::Find=finddepth -le 'finddepth(sub{m/\s/ and do{(my $a=$_) =~ s/\s/_/g; rename $_, $a}}, @ARGV)' .
perl -mFile::Find=finddepth -e 'finddepth(sub{($a=$_)=~y/ /_/and rename $_,$a}, @ARGV)' .
IFS=` `je co? To se má jako provést nic a výsledek nic se má uložit do proměnné? Snad jsi chtěl napsat
IFS=$"\n"A
for i in `find . -name \*\ \*`je co jako? To nikdy, opravdu nikdy nedělej! Když tak
find . -name '* *' | while read filename do ... donea jde to i bez
IFS. Místo mv "$i" `echo "$i" |tr ' ' _`se píše
mv "$i" "${a// /_}"No a používat na tohle find samozřejmě jde, ale asi bych to udělal perlem nebo nějak takhlefind -depth -name '* *' -exec rename 'my ($dir, $name) = m,(.*)/(.*),;$name=~y/ /_/;$_=join"/", $dir,$name' {} +a nebo rovnou tu verzi v perlu.
mv "$i" "${a// /_}"jsem samozřejmě myslelmv "$i" "${i// /_}"
To IFS je pretypovani oddelovace z mezery na enter :)Vážně? Tak to se asi musím něco přiučit
$ IFS=` > ` $ echo ">$IFS<" >< $ IFS=$'\n' $ echo ">$IFS<" > <
Funguje i verze od 16.12. 23:42 Fuky, kterou jsem nakonec pouzil.No jak chceš, je to tvůj boj, ale až budeš potřebovat přejmenovat pár desítek tisíc souborů, tak rozhodně zkus
find -depth -name '* *' -exec rename 'my@a=split"/";$a[$#a]=~y/ /_/;$_=join"/",@a' {} +nebo perlish. Přece jen to bude rychlejší.
#!/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. Změny jsou následující:
české znaky -> anglické
zruší všechny pomlčky a mezery na začátku názvu (hovado, které takové
názvy tvoří, by zasloužilo pár facek)
zvláštní znaky se nahradí '_', pomlčku beru na milost, ale ne na začátku
vyhodí se (zbytečné) '_' kolem pomlčky
násobné '_' se nahradí jediným výskytem
vše se převede na malá písmena
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 unicodedata
class RenameFiles:
def __init__(self):
if os.environ.get('OS','') == 'Windows_NT':
self.locale = "cp1250"
else: #probably linux
local = os.environ.get('LANG', '')
if '.' in local: #Fedora way
self.locale = local.split('.')[1]
else: #Debian
self.locale = local
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 = self.cleanString(fileName.decode(self.locale))
fileName = re.sub("^[-\ ]+", "", fileName) #delete space or dash at the beginning
invalid_stuff = re.compile(r"[^a-zA-Z0-9_\.-]+") #forbidden characters (non-alfanumerical)
fileName = invalid_stuff.sub("_", fileName.strip()) #replace invalid stuff and spaces by _,
fileName = re.sub("_+", "_", fileName) #squeeze continuous underscores to one _
fileName = re.sub("-+", "-", fileName) #squeeze continuous dashes to one _
fileName = re.sub("_*-_*", "-", fileName) #removes useless '_' round the dash
fileName = re.sub("_*\._*", ".", fileName) #removes useless '_' round the dot
fileName = re.sub("-*\.-*", ".", fileName) #removes useless '-' round the dot
fileName = fileName.lower() #lower case
valid_name=re.compile(r"^[a-z0-9_\.][a-z0-9_\.-]+$") #regular expression for feasible name
if not valid_name.match(fileName):
print "Warning: '%s' is still not valid name" % fileName
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
new = self.cleanName(fileName)
if (new != "" and new != fileName):
print "Renaming %s: %s -> %s" % (dir, fileName, new) #kontrolní výpis
os.rename(dir+os.sep+fileName, dir+os.sep+new)
return
def process_dir(self, dir):
"""process all files in the folder"""
assert type(dir) == str
for f in os.listdir(dir):
file = dir + os.sep + f
if os.path.isdir(file): #if it is directory
self.process_dir(file) #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__':
renamer = RenameFiles()
renamer.process_dir('.')
fileName = re.sub("_+", "_", fileName) #squeeze continuous underscores to one _
fileName = re.sub("-+", "-", fileName) #squeeze continuous dashes to one _
Podle mého laického názoru jsou tam naprosto zbytečné. V tu chvíli tam totiž žádné - už nemůže být a všechny _ jsou tam vždy jen jednou. A nebo taky je možné, že reguláry v pythonu fungují naprosto jinak než jinde
No a vůbec, ta práce s reguláry je schválně napsaná takto, aby se počítač pokudmožno nenudil, že? Spousta jich jde sdružit a taky co kdyby se skompilovaly jen jednou (aspoň pro ten objekt, když ne rovnou pro celou třídu) a nedělaly se pro každý soubor znova
_-_ na nic nepřevede, protože - není invalid_stuff. Když tak koukám na tu dokumentaci sre v Pythonu, tak to je teda pěkně nepohodlné proti perlu. Třeba kompilace jen jednou je tam brnkačka, děje se to transparentně a člověk o tom skoro ani neví a na využití byť jen hloupého (), aby člověk studoval kdo ví co.
__start_trash = re.compile(r'^[- ]+').sub
startCleaner = lambda x: __start_trash('', x)
__invalid_stuff = re.compile(r'[^a-zA-Z0-9.-]+').sub
invalidStuffRemover = lambda x: __invalid_stuff('_', x)
__useless_chars = re.compile(r'[-_]*([-.])\1*[-_]*').sub
uselessCharsRemover = lambda x: __useless_chars(r'\1', x)
validName = re.compile(r'^[a-z0-9_\.][a-z0-9_\.-]+$').match
def cleanName(self, fileName):
'''Convert the givne string into a form which is suitable for a file name'''
assert type(fileName) == str
fileName = self.cleanString(fileName.decode(self.locale))
fileName = self.startCleaner(fileName.strip()) #delete space or dash at the beginning
fileName = self.invalidStuffRemover(fileName) #replace invalid stuff and spaces by _,
fileName = self.uselessCharsRemover(fileName) #remove useless chars
fileName = fileName.lower() #lower case
if not self.validName(fileName):
print "Warning: '%s' is still not valid name" % fileName
return fileName.encode(self.locale)
Jak říkám v pythonu nemám moc praxe, ale asi takhle. Kdybych v tom měl napsaných tolik desítek tisíc řádků jako v perlu, tak by to bylo lepší. V pricipu jde o to, aby se toho co nejméně dělalo dvakrát. Když si uvědomím, že tohle kolem kompilace těch regexpů jen jednou za mě udělá perl aniž by si to 99% programátorů v perlu vůbec uvědomilo, tak se mi ten python zas až tak moc nelíbí, ale když si stím člověk pohraje, tak ty programy mohou vypadat k světu a zároveň být efektivní.
$ convmv bash: convmv: command not foundNe každý si do systému instaluje každou pičovinku, ale
find a rename (and or perl) má skoro každý. I když uvedené příklady jsou pro perlish rename.
Návod do žůžo shellu:
#!/usr/bin/zsh
setopt EXTENDED_GLOB
for f in **/*\ *(.) ; do mv "$f" "${f:h}/${${f:t}// /_}" ; done
Je to ale skoro nečitelné.
find . * -type f -print0 | xargs -0 rename ' ' _
. -name '*'. (Slušný člověk by použil něco jako '* *', ale to jsem o sobě nikdy netvrdil.) Díky.
Efektivita: Obrovská! Je to pomalý! Ale je to jednoduché a s pomocí manu to uplácá i taková lama jako já. Ještě ke všemu je to typická jednorázovka. Ale kupodivu jsem to tu nepsal ani pro tebe ani pro CIJOMILa(*), ale pro ty kdo začínají. Snad si to tu přečtou, vzpomenou si, až to budou potřebovat, a uplacaji si něco taky.
(*) Nejsem samolibý magor, jsem pouze samolibý.
Podle pořadí důležitosti: Adresáře: Přečti si otázku.Přečti si diskusi, otázka byla doplněna.
Tečka mezera hvězdička, tvoje následující odpověď: To je hodně debilně opsané . -name '*'.To hlavně nedělá to co by to dělat mělo.(Slušný člověk by použil něco jako '* *', ale to jsem o sobě nikdy netvrdil.) Díky. Efektivita: Obrovská! Je to pomalý! Ale je to jednoduché a s pomocí manu to uplácá i taková lama jako já. Ještě ke všemu je to typická jednorázovka. Ale kupodivu jsem to tu nepsal ani pro tebe ani pro CIJOMILa(*), ale pro ty kdo začínají.No, tak ti co začínají si doufám přečtou ten man pořádně a kouknou se jak se to dělá. Proč nepoužít
xargs? K čemu, když máme + za -exec ve findu? Bez -depth to s adresářema stejně nevyřešíš a jak se ti tam nějakej s mezerou v názvu vyskytne, tak to tvoje řešení prostě zhavaruje.Snad si to tu přečtou, vzpomenou si, až to budou potřebovat, a uplacaji si něco taky. (*) Nejsem samolibý magor, jsem pouze samolibý.Hmm, hlavně s křížkem po funuse, dále je zjevné, že jsi předchozí diskusi vůbec nečetl a prostě jsi jen tak něco plácl. Jen tak plácalů jsou mraky a jsou úplně k ničemu. Raději se řiď radou.
find . * má být jako co?
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.