El enfoque más directo es aprovechar la capa del sistema de archivos para transformar los nombres de los archivos. Desde Ubuntu 12.04, existe un sistema de archivos FUSE que transforma los nombres de archivo en nombres que admite VFAT de Windows: fuse-posixovl .
sudo mount.posixovl /media/sdb1
chown guillaume /media/sdb1
rsync -au ~/mail /media/sbd1/
O para evitar requerir acceso de root:
mkdir ~/mnt
/sbin/mount.posixovl -S /media/sdb1 ~/mnt
rsync -au ~/mail ~/mnt/
Los caracteres en los nombres de archivo que VFAT no acepta están codificados como %(XX)
donde XX
están los dígitos hexadecimales. A partir de POSIXovl 1.2.20120215, tenga en cuenta que un nombre de archivo como %(3A)
está codificado como sí mismo y se decodificará como :
, por lo que existe el riesgo de colisión si tiene nombres de archivo que contienen subcadenas del formulario %(XX)
.
Tenga en cuenta que POSIXovl no hace frente a nombres de archivo que son demasiado largos. Si el nombre codificado no cabe en 255 caracteres, el archivo no se puede almacenar.
POSIXovl almacena los permisos y la propiedad de Unix en los archivos llamados .pxovl.FILENAME
.
El siguiente bash ≥4 script copia ~/mail/foo:bar
a /media/usb99/mail/foo_bar
, y de manera similar para todos los archivos debajo ~/mail
. Se omiten los archivos que ya existen en el árbol de destino y que no son más antiguos que el origen.
#!/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
Este script funciona bajo zsh con modificaciones menores: reemplazar shopt -s dotglob globstar
por setopt dot_glob
y [[ $target -ot $source ]]
por [[ ! -e $target || $target -ot $source ]]
.
Aquí hay un zsh de dos líneas (tres si cuenta las cargas automáticas). Es más corto, pero bastante avanzado y no muy legible.
autoload zargs zmv
zargs -- ~/mail/**/*(/e\''REPLY=/media/usb99/${${REPLY#$HOME/}//:/_}'\') -- mkdir -p --
zmv -C -Q -o -pu '~/mail/(**/)(*)(.)' '/media/usb99/mail/${1//:/_}${2//:/_}'
- La
zargs
línea es equivalente a mkdir -p ~/mail/**/*(…)
, excepto que no se bombardeará si la longitud acumulada de los nombres de directorio es demasiado larga. Esa línea crea los directorios de destino según sea necesario.
~/mail/**/*(/)
se expande a todos los directorios debajo ~/mail
(directorios solo debido al (/)
final).
(/e\''…'\')
selecciona solo directorios y ejecuta el código dentro de '...' para transformar cada nombre de archivo, que se almacena en la REPLY
variable.
${${REPLY#$HOME/}//:/_}
elimina el prefijo correspondiente al directorio de origen y cambia :
a _
.
zmv -C
copia cada archivo que coincide con su primer operando (un patrón zsh) al nombre de archivo obtenido al expandir su segundo operando.
-o -pu
dice pasar -pu
a la cp
utilidad, para preservar los permisos y copiar solo los archivos actualizados. (Podríamos decirle a zsh que realice la verificación de actualización; sería un poco más rápido pero aún más críptico).
(.)
selecciona solo archivos regulares. -Q
dice que esto debe analizarse como un calificador global y no como un .
paréntesis alrededor que indica una subexpresión.
$1
y $2
en el texto de reemplazo coinciden las expresiones entre paréntesis (**/)
y *
. ( **
pierde su significado especial como cero o más niveles de subdirectorio si está entre paréntesis, a menos que los paréntesis contengan exactamente **/
).
Inicialmente pensé en usar pax , que es una herramienta de archivo (aquí diseñada para usarse en modo de transferencia) que tiene una función de cambio de nombre de archivo (su -s
opción). Sin embargo, las opciones -s
y -u
no funcionan juntas (la definición POSIX de pax literalmente dice que -u
debe verificar un archivo del mismo nombre en el árbol de destino, en lugar del nombre del archivo transformado por -s
; la implementación de pax en Ubuntu sigue la especificación literalmente en lugar de útilmente). Todavía es posible usarlo para hacer enlaces duros renombrados y luego copiar los enlaces duros (con rsync -au
o pax -rw -pp -u
) a los otros medios, pero se siente más problemas de lo que vale.
cd ~/mail
mkdir -p /media/usb99/mail
pax -rw -l -pp -s '!:!_!g' . ../mail.colonless
rsync -au ../mail.colonless/ /media/usb99/mail/
Lo que hago con mi memoria USB y disco USB móvil es particionarlos con 2 particiones: una FAT32 y una ext4. El primero que puedo usar para intercambiar datos con usuarios que no son de Linux, el segundo para mi uso personal con mis sistemas Ubuntu (y tal vez para intercambiar con otros usuarios de Linux). En una partición ext4, no tendrá el problema ":".
fuente
Podrías usar
tar
para crear un archivo. De esta manera, no tiene que cambiar los nombres y puede guardarlo en el sistema de archivos que desee.fuente