mover 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/bin/sh
  2. usage () {
  3. cat <<EOF>&2
  4. ${0##*/} FOLDERS DEST
  5. Merge FOLDERS content into DEST. Existing files and folders will remain. It does
  6. not overwrite by default. Empty folders are ignored. The resulting hierarchy is:
  7. DEST/FOLDER1/<folder1data>
  8. DEST/FOLDER2/<folder2data>
  9. ...
  10. Options:
  11. -f: Overwrite destination.
  12. -r: Remove empty folders.
  13. WARNING: Do not use over filenames with newlines.
  14. EOF
  15. }
  16. OPT_OVERWRITE=false
  17. OPT_DELEMPTY=false
  18. while getopts ":fhr" opt; do
  19. case $opt in
  20. h)
  21. usage
  22. exit 1 ;;
  23. f)
  24. OPT_OVERWRITE=true ;;
  25. r)
  26. OPT_DELEMPTY=true ;;
  27. \?)
  28. usage
  29. exit 1 ;;
  30. esac
  31. done
  32. shift $((OPTIND - 1))
  33. if [ $# -eq 0 ]; then
  34. usage
  35. exit 1
  36. fi
  37. ## The counter is used to process all arguments but the last one. We can get the
  38. ## last argument with an 'eval'. (Safe here.)
  39. DEST="$(eval "echo \$$#")"
  40. count=0
  41. for i ; do
  42. count=$((count+1))
  43. [ $count -eq $# ] && break
  44. while IFS= read -r FILE; do
  45. DESTFILE="$DEST/$FILE"
  46. if [ ! -e "$DESTFILE" ] || $OPT_OVERWRITE; then
  47. mkdir -p "$(dirname "$DESTFILE")"
  48. mv -v "$i/../$FILE" "$DESTFILE"
  49. if $OPT_DELEMPTY; then
  50. PARENT="$FOLDER/../$FILE"
  51. PARENT="${PARENT%/*}"
  52. rmdir "$PARENT" 2>/dev/null
  53. fi
  54. fi
  55. ## We switch to $i so that 'find' strips the parent dirs from the path.
  56. done <<EOF
  57. $(cd -- "$i/.." && find "$(basename ${i})" \( -type f -o -type l \) )
  58. EOF
  59. done