最も簡単なアプローチは、ファイルシステム層を活用してファイル名を変換することです。Ubuntu 12.04以降、ファイル名をWindowsのVFATがサポートする名前に変換するFUSEファイルシステムがあります:fuse-posixovl 。
sudo mount.posixovl /media/sdb1
chown guillaume /media/sdb1
rsync -au ~/mail /media/sbd1/
または、rootアクセスを必要としないようにするには:
mkdir ~/mnt
/sbin/mount.posixovl -S /media/sdb1 ~/mnt
rsync -au ~/mail ~/mnt/
VFATは受け入れないことを、ファイル名の文字は、次のようにエンコードされている%(XX)
場所をXX
16進数です。POSIXovl 1.2.20120215の時点で、などのファイル名%(3A)
はそれ自体としてエンコードされ:
、としてデコードされることに注意してください%(XX)
。
POSIXovlは長すぎるファイル名に対応していないことに注意してください。エンコードされた名前が255文字に収まらない場合、ファイルを保存できません。
POSIXovlは、UNIXの許可と所有権をというファイルに保存します.pxovl.FILENAME
。
次のbash≥4スクリプトは、にコピー~/mail/foo:bar
し/media/usb99/mail/foo_bar
ます~/mail
。宛先ツリーにすでに存在し、ソースより古くないファイルはスキップされます。
#!/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
このスクリプトは、軽微な改変とzshの下に動作します:置き換えるshopt -s dotglob globstar
ことにより、setopt dot_glob
および[[ $target -ot $source ]]
によって[[ ! -e $target || $target -ot $source ]]
。
zshの2ライナー(オートロードをカウントする場合は3ライナー)があります。短いですが、かなり高度で読みにくいです。
autoload zargs zmv
zargs -- ~/mail/**/*(/e\''REPLY=/media/usb99/${${REPLY#$HOME/}//:/_}'\') -- mkdir -p --
zmv -C -Q -o -pu '~/mail/(**/)(*)(.)' '/media/usb99/mail/${1//:/_}${2//:/_}'
- この
zargs
行はmkdir -p ~/mail/**/*(…)
、ディレクトリ名の累積された長さが長すぎる場合に爆破されないことを除いて、と同等です。その行は、必要に応じてターゲットディレクトリを作成します。
~/mail/**/*(/)
下のすべてのディレクトリに展開します~/mail
(ディレクトリ(/)
は最後にあるため)。
(/e\''…'\')
ディレクトリのみを選択し、「…」内のコードをさらに実行して、REPLY
変数に保存されている各ファイル名を変換します。
${${REPLY#$HOME/}//:/_}
ソースディレクトリに対応するプレフィックスを削除し、に変更:
し_
ます。
zmv -C
第1オペランド(zshパターン)に一致する各ファイルを、第2オペランドを展開して取得したファイル名にコピーします。
-o -pu
許可を保持し、更新されたファイルのみをコピーするため-pu
に、cp
ユーティリティに渡すように指示します。(更新チェックを実行するようにzshに指示することができます。それは少し高速ですが、さらに不可解です。)
(.)
通常のファイルのみを選択します。-Q
これは.
、サブ式を示す括弧で囲まれたものとしてではなく、グロブ修飾子として解析されることを示しています。
$1
および$2
置換テキストでは、括弧で囲まれた式(**/)
とに一致します*
。(**
括弧内に正確に**/
。が含まれていない限り、括弧内にある場合、サブディレクトリレベルが0個以上であるという特別な意味を失います。)
最初はpaxを使用することを考えました。これは、ファイル名変更機能(-s
オプション)を備えたアーカイブツール(ここではパススルーモードで使用することを目的としています)です。ただし、オプション-s
と-u
オプションは一緒に機能しません(paxのPOSIX定義では、文字列-u
によって変換されるファイル名ではなく、宛先ツリー内の同じ名前のファイルをチェックする必要があると言われてい-s
ます; Ubuntuのpax実装は、便利に)。名前変更されたハードリンクを作成するためにそれを利用し、ハードリンクを(rsync -au
またはでpax -rw -pp -u
)他のメディアにコピーすることはまだ可能ですが、それは価値以上のトラブルを感じます。
cd ~/mail
mkdir -p /media/usb99/mail
pax -rw -l -pp -s '!:!_!g' . ../mail.colonless
rsync -au ../mail.colonless/ /media/usb99/mail/