-
Notifications
You must be signed in to change notification settings - Fork 39
/
fatcp
executable file
·61 lines (52 loc) · 1.59 KB
/
fatcp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#! /usr/bin/bash
# Script for safe copying to FAT32 filesystems.
# All bad characters are replaced by '_' (underscore) when copying.
# File conflicts (e.g. 'foo?' and 'foo:' are both mapped to 'foo_') are not checked - using 'cp -i' is recommended.
# Some resources:
# http://askubuntu.com/questions/11634/how-can-i-substitute-colons-when-i-rsync-on-a-usb-key
#
# Simple (stupid) alternative:
# find -type f -name '*.pat' -print0 | tar -c -f - --null --files-from - | tar -C /path/to/dst -v -x -f - --show-transformed --transform 's/?/_/g'
#
# two arguments are accepted
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <src path> <dst path>"
exit 1
fi
base=$(realpath "$1")
basedir=$(dirname "$base")
dst=$(realpath "$2")
# $dst must be existing dir
if [[ ! -d "$dst" ]]; then
echo "Target directory '$dst' does not exist."
exit 1
fi
# 'cp' alias
CP="cp -i --preserve=all"
# characters that will be replaced with '_'
BADCHARS='<>|;:!?"*\+'
# enhance globbing
shopt -s dotglob globstar
# function creating target file/dir name
mk_target() {
local target=${1#"$basedir"}
echo "$dst/${target//[$BADCHARS]/_}"
}
# dirs and files are handled differently
if [[ -d "$base" ]]; then
target=$(mk_target "$base")
mkdir "$target"
for src in "$base"/**/*; do
target=$(mk_target "$src")
if [[ -d "$src" ]]; then
mkdir -p -- "$target"
elif [[ "$src" != "$target" ]]; then
$CP -- "$src" "$target"
fi
done
elif [[ -f "$base" ]]; then
target=$(mk_target "$base")
if [[ "$src" != "$target" ]]; then
$CP -- "$base" "$target"
fi
fi