GNU/Linux >> Znalost Linux >  >> Linux

Jak hromadně přejmenovat soubory s neplatným kódováním nebo hromadně nahradit neplatné kódované znaky?

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. Obvykle find prochází různě (ale ne na šířku).
  • -print0 zajišťuje find výstup je oddělený nulou, takže jej můžeme číst pomocí read -d '' do file 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ázvem resume a résumé ve stejném adresáři), vydá varování. Nechcete jej přejmenovat, protože na některých systémech mv 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:

  1. mv Motörhead/Encöding Motörhead/Encoding
  2. 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.


Linux
  1. Jak převést soubory do kódování UTF-8 v Linuxu

  2. Jak přejmenovat soubory v Linuxu

  3. Jak přejmenovat více souborů pomocí funkce Najít?

  1. Jak přejmenovat sadu souborů se vzorem?

  2. Jak přejmenuji soubory s mezerami pomocí prostředí Linux?

  3. Jak odstranit neplatné znaky z názvů souborů?

  1. Jak šifrovat soubory pomocí gocryptfs na Linuxu

  2. Jak rozbalit soubory v Linuxu (s příklady)

  3. Jak rekurzivně nahradit znaky sed?