Vím, že to není přesně to, co jste chtěli, ale pokud znáte původní kódování, možná můžete použít convmv
změnit kódování na UTF-8, což by mělo vyřešit většinu problémů.
Toto fungovalo pro mě na složce s některými neplatně zakódovanými polskými názvy souborů:
convmv -f cp1250 -t utf8 -r .
Všimněte si, že tento příkaz ve skutečnosti nic nepřejmenovává; přidat --notest
možnost skutečně přejmenovat soubory.
Pokud chcete přejmenovat soubory a, budete mít problémy adresářů současně. Přejmenování pouze souboru je dost snadné. Ale chcete se ujistit, že adresáře jsou také přejmenovány. Nemůžete jednoduše mv Motörhead/Encöding Motorhead/Encoding
od Motorhead
nebude v době hovoru existovat.
Potřebujeme tedy nejprve hloubkově projít všechny soubory a složky a poté přejmenovat pouze aktuální soubor nebo složku. Následující funguje s GNU find
a Bash 4.2.42 na mém OS X.
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
Regulární výraz můžete změnit pomocí new="${f//[\\\/\:\*\?\"<>|]/}"
pokud chcete nahradit cokoli, co Windows nezvládne.
Uložte tento skript jako rename.sh
, udělejte jej spustitelný pomocí chmod +x rename.sh
. Pak to nazvěte jako rename.sh /some/path
.
Ujistěte se, že jste vyřešili všechny kolize názvů souborů („Notice
” oznámení).
Pokud jste si naprosto jisti provádí správné nahrazení, odstraňte echo
ze skriptu skutečně přejmenovat věci místo toho, aby jen tiskl to, co dělá.
Pro jistotu bych to doporučil nejprve otestovat na malé podmnožině souborů.
Vysvětlení možností
Abych vysvětlil, co se zde děje:
-depth
zajistí, že adresáře budou rekurzovány nejdříve do hloubky, takže můžeme vše "srolovat" od konce. Obvyklefind
prochází různě (ale ne na šířku).-print0
zajišťujefind
výstup je oddělený nulou, takže jej můžeme číst pomocíread -d ''
dofile
variabilní. To nám pomůže vypořádat se se všemi druhy podivných názvů souborů, včetně těch s mezerami a dokonce i s řádky.- Dostaneme adresář souboru s
dirname
. Nezapomeňte vždy správně citovat proměnné, jinak by jakákoli cesta s mezerami nebo kulovitými znaky narušila tento skript. - Získáme skutečný název souboru (nebo adresáře) s
basename
. - Potom odstraníme všechny neplatné znaky z
$f
pomocí Bashových možností výměny strun. Neplatné znamená cokoli, co není malé nebo velké písmeno, číslice nebo lomítko (\/
), tečka (\.
), podtržítko nebo minus-pomlčka. - Pokud
$f
je již čistý (vyčištěný název je totožný s aktuálním názvem), přeskočte jej. - Pokud
$new
již existuje v adresáři$d
(např. máte soubory s názvemresume
arésumé
ve stejném adresáři), vydá varování. Nechcete jej přejmenovat, protože na některých systémechmv foo foo
způsobuje problém. Jinak, - Původní soubor (nebo adresář) nakonec přejmenujeme na nový název
Protože to bude fungovat pouze v nejhlubší hierarchii, přejmenování Motörhead/Encöding
na Motorhead/Encoding
se provádí ve dvou krocích:
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
To zajistí, že všechny výměny budou provedeny ve správném pořadí.
Ukázkové soubory a zkušební provoz
Předpokládejme některé soubory v základní složce nazvané test
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
Zde je výstup z běhu v režimu ladění (s echo
před mv
), tj. příkazy, které by byly volány, a varování před kolizí:
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
Všimněte si absence zpráv pro with-hyphen.txt
, schedule
a test
sám.