-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrename-map.sh
More file actions
108 lines (92 loc) · 2.52 KB
/
Copy pathrename-map.sh
File metadata and controls
108 lines (92 loc) · 2.52 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env bash
set -euo pipefail
MAP_FILE=".file-organizer-map.json"
usage() {
cat <<EOF
Usage: $(basename "$0") <command> <target-dir>
Commands:
save <dir> Read rename map from stdin (JSON) and save to <dir>/$MAP_FILE
show <dir> Print the current rollback map
rollback <dir> Undo all renames/moves recorded in the map
reconcile <dir> Remove entries whose source still exists (rename never happened)
clear <dir> Delete the rollback map
EOF
exit 1
}
[[ $# -lt 2 ]] && usage
CMD="$1"
TARGET_DIR="$2"
MAP_PATH="$TARGET_DIR/$MAP_FILE"
case "$CMD" in
save)
# Reads JSON from stdin: [{"from":"old/path","to":"new/path"}, ...]
cat > "$MAP_PATH"
echo "Saved rollback map to $MAP_PATH"
;;
show)
if [[ ! -f "$MAP_PATH" ]]; then
echo "No rollback map found at $MAP_PATH"
exit 1
fi
cat "$MAP_PATH"
;;
rollback)
if [[ ! -f "$MAP_PATH" ]]; then
echo "No rollback map found at $MAP_PATH"
exit 1
fi
# Parse JSON array and reverse each operation (last-first for correct ordering)
entries=$(python3 -c "
import json, sys
with open('$MAP_PATH') as f:
ops = json.load(f)
for op in reversed(ops):
print(op['to'] + '\t' + op['from'])
")
errors=0
count=0
while IFS=$'\t' read -r src dst; do
if [[ -e "$src" ]]; then
mkdir -p "$(dirname "$dst")"
mv -- "$src" "$dst"
echo " ✓ $src → $dst"
((count++))
else
echo " ✗ Not found: $src"
((errors++))
fi
done <<< "$entries"
echo ""
echo "Rollback complete: $count restored, $errors errors"
# Clean up empty _unknown directory if it exists
[[ -d "$TARGET_DIR/_unknown" ]] && rmdir --ignore-fail-on-non-empty "$TARGET_DIR/_unknown" 2>/dev/null || true
;;
clear)
if [[ -f "$MAP_PATH" ]]; then
rm "$MAP_PATH"
echo "Cleared rollback map at $MAP_PATH"
else
echo "No rollback map to clear."
fi
;;
reconcile)
if [[ ! -f "$MAP_PATH" ]]; then
echo "No rollback map found at $MAP_PATH"
exit 1
fi
# Remove entries where the original file still exists (rename never executed)
python3 -c "
import json, os
with open('$MAP_PATH') as f:
ops = json.load(f)
kept = [op for op in ops if not os.path.exists(op['from'])]
removed = len(ops) - len(kept)
with open('$MAP_PATH', 'w') as f:
json.dump(kept, f, indent=2, ensure_ascii=False)
print(f'Reconciled: {len(kept)} kept, {removed} removed (source still exists)')
"
;;
*)
usage
;;
esac