Am einfachsten ist es, die Dateisystemebene zu nutzen, um die Dateinamen zu transformieren. Seit Ubuntu 12.04 gibt es ein FUSE- Dateisystem, das Dateinamen in Namen umwandelt, die von Windows VFAT unterstützt werden: fuse-posixovl
.
sudo mount.posixovl /media/sdb1
chown guillaume /media/sdb1
rsync -au ~/mail /media/sbd1/
Oder um zu vermeiden, dass Root-Zugriff erforderlich ist:
mkdir ~/mnt
/sbin/mount.posixovl -S /media/sdb1 ~/mnt
rsync -au ~/mail ~/mnt/
Zeichen in Dateinamen , dass VFAT nicht akzeptiert codiert sind , als %(XX)wo XXsind hexadezimale Ziffern. Achten Sie ab POSIXovl 1.2.20120215 darauf, dass ein Dateiname wie derselbe als solcher %(3A)codiert und als solcher decodiert wird. Daher :besteht Kollisionsgefahr, wenn Sie Dateinamen haben, die Teilzeichenfolgen des Formulars enthalten %(XX).
Beachten Sie, dass POSIXovl mit zu langen Dateinamen nicht zurechtkommt. Wenn der verschlüsselte Name nicht in 255 Zeichen passt, kann die Datei nicht gespeichert werden.
POSIXovl speichert Unix-Berechtigungen und -Eigentum in den aufgerufenen Dateien .pxovl.FILENAME.
Die folgenden bash ≥4 Skript kopiert ~/mail/foo:barzu/media/usb99/mail/foo_bar und für alle Dateien unter~/mail . Dateien, die bereits in der Zielstruktur vorhanden sind und nicht älter als die Quelle sind, werden übersprungen.
#!/bin/bash
set -e
shopt -s dotglob globstar
for source in "$HOME"/mail/**/*; do
target=/media/usb99/${source#"$HOME"/}
target=${target//:/_}
if [[ -d $source ]]; then
mkdir -p -- "$target"
elif [[ $target -ot $source ]]; then
cp -p -- "$source" "$target"
fi
done
Dieses Skript funktioniert unter zsh mit geringfügigen Änderungen: Ersetzen shopt -s dotglob globstardurchsetopt dot_glob und [[ $target -ot $source ]]durch [[ ! -e $target || $target -ot $source ]].
Hier ist ein Zsh-Two-Liner (drei, wenn Sie die Autoloads zählen). Es ist kürzer, aber ziemlich weit fortgeschritten und wenig lesbar.
autoload zargs zmv
zargs -- ~/mail/**/*(/e\''REPLY=/media/usb99/${${REPLY#$HOME/}//:/_}'\') -- mkdir -p --
zmv -C -Q -o -pu '~/mail/(**/)(*)(.)' '/media/usb99/mail/${1//:/_}${2//:/_}'
- Das
zargs Zeile ist äquivalent zu mkdir -p ~/mail/**/*(…), außer dass sie nicht bombardiert wird, wenn die kumulierte Länge der Verzeichnisnamen zu lang ist. Diese Zeile erstellt die Zielverzeichnisse nach Bedarf.
~/mail/**/*(/) Erweitert alle Verzeichnisse unter ~/mail (Verzeichnisse nur aufgrund der (/)am Ende).
(/e\''…'\')Wählt nur Verzeichnisse aus und führt den Code innerhalb von '…' weiter aus, um jeden in der REPLYVariablen gespeicherten Dateinamen zu transformieren .
${${REPLY#$HOME/}//:/_} Entfernt das Präfix, das dem Quellverzeichnis entspricht, und ändert es : zu _.
zmv -C kopiert jede Datei, die ihrem ersten Operanden (einem zsh-Muster) entspricht, in den Dateinamen, der durch Erweitern ihres zweiten Operanden erhalten wird.
-o -pusagt an -pudas cpDienstprogramm übergeben, um Berechtigungen zu erhalten und nur aktualisierte Dateien zu kopieren. (Wir könnten zsh anweisen, die Update-Prüfung durchzuführen. Sie wäre etwas schneller, aber noch kryptischer.)
(.)Wählt nur normale Dateien aus. -Qgibt an, dass dies als Glob-Qualifikationsmerkmal analysiert werden soll und nicht als .Klammer, die einen Unterausdruck angibt.
$1und $2stimmen im Ersetzungstext mit den Ausdrücken in Klammern (**/)und überein *. ( **Verliert seine spezielle Bedeutung als null oder mehr Unterverzeichnisebenen, wenn es in Klammern steht, es sei denn, die Klammern enthalten genau **/.)
Ursprünglich dachte ich an die Verwendung von pax , einem Archivierungstool (hier für den Passthrough-Modus vorgesehen) mit einer Funktion zum Umbenennen von Dateien ( -soptional). Die Optionen -sund -ufunktionieren jedoch nicht zusammen (die POSIX-Definition von pax besagt wörtlich, dass -ueine Datei mit demselben Namen im Zielbaum geprüft werden muss und nicht der von transformierte Dateiname -s; die pax-Implementierung in Ubuntu folgt der Spezifikation wörtlich und nicht nützlich). Es ist immer noch möglich, damit umbenannte Hardlinks zu erstellen und die Hardlinks dann (mit rsync -auoder pax -rw -pp -u) auf die anderen Medien zu kopieren , aber es bereitet mehr Mühe als es wert ist.
cd ~/mail
mkdir -p /media/usb99/mail
pax -rw -l -pp -s '!:!_!g' . ../mail.colonless
rsync -au ../mail.colonless/ /media/usb99/mail/