Advertisement
pintcat

unzoom v1.6 final (that should do *hopefully*)

Jan 29th, 2016
272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.25 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. DEF_SOURCE=/media/H6_SD/FOLDER01/
  4. DEF_TARGET=/media/ramdisk/
  5. DEF_FTYPE=.WAV
  6. DEF_IFS=$IFS
  7. SOURCE=$DEF_SOURCE
  8. TARGET=$DEF_TARGET
  9. FTYPE=$DEF_FTYPE
  10. TMP_FLIST=
  11. LIST=empty
  12. STAT=ok
  13. typeset -i TMP_COUNT=0
  14. typeset -i FAIL=0
  15.  
  16. function ERROR() # displays error message and explains how things work out
  17. {
  18.     printf "\033[0;31mError! $1\033[0;32m\n\n"
  19.     cat <<EOF
  20.  unzoom can be used to extract files from the folder structure created by the ZOOM H6 recorder. It seeks the files inside these
  21.  folders, selects them by timestamp entries (year, month, day, hour) and/or file numbers and - if desired - copies them to a
  22.  custom target folder.
  23.  
  24.  Usage: unzoom.bash [-estymdhn]
  25.  Options: -e <extension> ..... Set file type (default is $DEF_FTYPE)
  26.           -s <path> .......... Set source directory (default is $DEF_SOURCE)
  27.           -t <path> .......... Set target directory (default is $DEF_TARGET)
  28.           -y <n1,n2,nX-nY> ... Filter by year (must be written exactly as in the file list)
  29.           -m <n1,n2,nX-nY> ... Filter by month
  30.           -d <n1,n2,nX-nY> ... Filter by day
  31.           -h <n1,n2,nX-nY> ... Filter by hour
  32.           -n <n1,n2,nX-nY> ... Filter by file number
  33.  
  34.  When setting a file extension, consider that everything is case sensitive. Each filter option must be followed by either a single
  35.  number, several numbers separated by comma or a range of numbers specified by the first and the last number divided by a "-". And
  36.  remember: If you intend to filter by year, the value must be written exactly as given in the file list (i.e. if year is 2010 then
  37.  write 2010 and not just 10). You can combine all the filter options at discretion. Using no filter will of course bring up the
  38.  entire file list.
  39.  Beware: When copying files, all existing files with same names in the target folder will be overwritten without request!
  40. EOF
  41.     printf "\033[0m\n"
  42.     exit 1
  43. }
  44.  
  45. function GET_PATH() # retrieves absolute path to given folder if -s or -t option was called
  46. {
  47.     NEW_PATH=$1
  48.     if [ -d "$NEW_PATH" ]; then
  49.     cd "$NEW_PATH"
  50.     NEW_PATH=$(pwd)"/"
  51.     else
  52.     if [ -z $2 ]; then
  53.         ERROR "Directory \"$NEW_PATH\" does not exist."
  54.     else
  55.         echo -e "\n\033[0;31m\"$NEW_PATH\" not found - nothing changed.\033[0m"
  56.         PRINT_LIST
  57.     fi
  58.     fi
  59. }
  60.  
  61. function CHECK_MATCH() # checks if current file specs match with filter settings and calls BUILD_LIST() function
  62. {
  63.     typeset -i NUM=$(echo "obase=10;$1" | bc)
  64.     if [ $NUM_LO -eq -1 ] || [ $NUM -ge $NUM_LO ]; then
  65.     if [ $NUM_HI -eq -1 ] || [ $NUM -le $NUM_HI ]; then BUILD_LIST; fi
  66.     fi
  67. }
  68.  
  69. function BUILD_LIST() # builds file lists, skips existing lines and counts gathered entries
  70. {
  71.     NEW_LIST=$(printf "$NEW_LIST")"\n"$LINE
  72.     TMP_LINE=$(printf "/$FILE\t    time stamp:  $YEAR $MONTH $DAY $HOUR (year, month, day, hour)")
  73.     PREV_IFS=$IFS
  74.     IFS=$'\n'
  75.     for SEG in $(printf "$TMP_FLIST"); do
  76.     if [ "$TMP_LINE" = "$SEG" ]; then TMP_LINE=; fi
  77.     done
  78.     IFS=$PREV_IFS
  79.     if [ -n "$TMP_LINE" ]; then
  80.     TMP_FLIST=$(printf "$TMP_FLIST")"\n"$TMP_LINE
  81.     TMP_COUNT=$TMP_COUNT+1
  82.     fi
  83. }
  84.  
  85. function CHECK_ARG() # parses argument, performs integrity check and calls FILTER() function
  86. {                    # $STAT must be "ok" to proceed to FILTER() function; otherwise only check is performed
  87.     IFS=","
  88.     for VAL in $1; do
  89.     NUM_LO=${VAL%-*}
  90.     if [ -z $NUM_LO ]; then NUM_LO=-1; fi
  91.     NUM_HI=${VAL#*-}
  92.     if [ -z $NUM_HI ]; then NUM_HI=-1; fi
  93.     if [[ ! $NUM_LO =~ ^-?[0-9]+$ ]] || [[ ! $NUM_HI =~ ^-?[0-9]+$ ]]; then
  94.         if [ -z "$NEW_OPT" ]; then
  95.         ERROR "Missing or wrong argument for \"$2\""
  96.         else
  97.         FILTER_OPT=$OLD_FILTER
  98.         echo -ne "\n\033[0;31mNumerical value expected for \"$2\" - skipping filter treatment.\033[0m\n"
  99.         PRINT_LIST
  100.         fi
  101.     fi
  102.     done
  103.     IFS=$DEF_IFS
  104.     if [ $STAT = ok ]; then FILTER $1 $2; fi
  105. }
  106.  
  107. function FILTER() # reads and filters the files according to the filter options set by the user
  108. {
  109.     if [ "$LIST" = empty ]; then
  110.     IFS=$DEF_IFS
  111.     for PROJECT in $(ls "$SOURCE"); do
  112.         if [ -d "$SOURCE$PROJECT" ]; then
  113.         if ls "$SOURCE$PROJECT"/*$FTYPE >/dev/null 2>/dev/null; then
  114.             if [ "$LIST" = empty ]; then LIST=; fi
  115.             LIST=$(printf "$LIST")"\n"$(ls -gn --time-style=long-iso "$SOURCE$PROJECT"/*$FTYPE)
  116.         fi
  117.         fi
  118.     done
  119.     fi
  120.     if [ ! "$LIST" = empty ]; then
  121.     IFS=$'\n'
  122.     for LINE in $(printf %b "$LIST"); do
  123.         if [ -n "$LINE" ]; then
  124.         DATE=$(echo -e $(echo $LINE | sed 's/ /\\n/g') | sed -n '5p')
  125.         YEAR=$(echo -e $(echo $DATE | sed 's/-/\\n/') | sed -n '1p')
  126.             MONTH=$(echo -e $(echo $DATE | sed 's/-/\\n/g') | sed -n '2p')
  127.             DAY=$(echo -e $(echo $DATE | sed 's/-/\\n/g') | sed -n '3p')
  128.         TIME=$(echo -e $(echo $LINE | sed 's/ /\\n/g') | sed -n '6p')
  129.             HOUR=${TIME%:*}
  130.         FILE=${LINE#*\ /}
  131.         PNAME=${FILE%/*}
  132.         FRONT=${FILE#$PNAME/ZOOM}
  133.         REAR=${FRONT#????}
  134.         if [ ! $1 = nothing ]; then
  135.             if [ $2 = h ]; then CHECK_MATCH $HOUR; fi
  136.             if [ $2 = d ]; then CHECK_MATCH $DAY; fi
  137.             if [ $2 = m ]; then CHECK_MATCH $MONTH; fi
  138.             if [ $2 = y ]; then CHECK_MATCH $YEAR; fi
  139.             if [ $2 = n ]; then CHECK_MATCH ${FRONT%$REAR}; fi
  140.         else
  141.             BUILD_LIST
  142.         fi
  143.         fi
  144.     done
  145.     IFS=","
  146.     fi
  147.     IFS=$DEF_IFS
  148.     LIST=$(printf "$NEW_LIST")
  149.     NEW_LIST=
  150.     FLIST=$TMP_FLIST
  151.     TMP_FLIST=
  152.     COUNT=$TMP_COUNT
  153.     TMP_COUNT=0
  154. }
  155.  
  156. function BACKUP() # saves variable for PRINT_LIST() function and writes them back if error occurs
  157. {
  158.     if [ -z $1 ]; then
  159.     FILTER_OPT=$OLD_FILTER
  160.     FLIST=$OLD_FLIST
  161.     FTYPE=$OLD_FTYPE
  162.     SOURCE=$OLD_SOURCE
  163.     LIST=$OLD_LIST
  164.     else
  165.     OLD_FILTER=$FILTER_OPT
  166.     OLD_FLIST=$FLIST
  167.     OLD_FTYPE=$FTYPE
  168.     OLD_SOURCE=$SOURCE
  169.     OLD_LIST=$LIST
  170.     fi
  171. }
  172.  
  173. function PRINT_LIST() # checks if file list contains something, prints it out and asks for next steps
  174. {
  175.     if [ -z $1 ]; then
  176.     if [ -z "$FLIST" ]; then
  177.         if [ -z $MENU_TRG ]; then
  178.         ERROR $ERROR_MSG.
  179.         else
  180.         echo -e "\n\033[0;31m"$ERROR_MSG" - nothing changed.\033[0m"
  181.         BACKUP
  182.         PRINT_LIST
  183.         fi
  184.     fi
  185.     printf "$FLIST\n"
  186.     fi
  187.     MENU_TRG=on
  188.     echo -e "\n$COUNT files selected. Source is: "\"$SOURCE\""; target is: "\"$TARGET\"". You may now press..."
  189.     echo -e "\033[0;32m(C)\033[0m to copy these files to target,       \033[0;32m(E)\033[0m to change file type & reread,        \
  190. \033[0;32m(S)\033[0m to change source & reread, \033[0;32m(T)\033[0m to change target, "
  191.     echo -ne "\033[0;32m(F)\033[0m to apply some (more) filter options, \033[0;32m(U)\033[0m to undo last filter option & reread, \
  192. \033[0;32m(R)\033[0m to reset filter & reread,  \033[0;32mENTER\033[0m to cancel & quit: "
  193.     read -n 1 OPT
  194.     echo
  195.     case $OPT in
  196.     c|C)
  197.         echo
  198.         IFS=$'\n'
  199.         typeset -i COUNT=0
  200.         for PROCESS in $(printf "$FLIST"); do
  201.         FILE_PATH=${PROCESS%$'\t'"    time stamp:"*}
  202.         if cp -v --preserve=timestamps $FILE_PATH $TARGET; then
  203.             COUNT=$COUNT+1
  204.         else
  205.             FAIL=$FAIL+1
  206.         fi
  207.         done
  208.         IFS=$DEF_IFS
  209.         echo -e "\nDone - "$COUNT" file(s) copied, "$FAIL" failed."
  210.         PRINT_LIST 1
  211.         ;;
  212.     f|F)
  213.         echo -ne "Possible options are \033[0;32my m d h\033[0m and \033[0;32mn\033[0m plus corresponding value. Enter new filter options ("
  214.         if [ -z "$FILTER_OPT" ]; then
  215.         read -p "none used so far): " NEW_OPT
  216.         else
  217.         read -p "current are \"${FILTER_OPT#\ *}\"): " NEW_OPT
  218.         fi
  219.         if [ -z "$NEW_OPT" ]; then PRINT_LIST 1; fi
  220.         ERROR_MSG="New filter setting would result in an empty list"
  221.         BACKUP save
  222.         FILTER_OPT=$NEW_OPT
  223.         STAT=check
  224.         PARSE_OPT_MENU
  225.         FILTER_OPT=$OLD_FILTER" "$NEW_OPT
  226.         STAT=ok
  227.         PARSE_OPT_MENU
  228.         PRINT_LIST
  229.         ;;
  230.     u|U)
  231.         if [ -z "$FILTER_OPT" ]; then
  232.         echo -e "\n\033[0;31mNo filter used - nothing to undo.\033[0m"
  233.         PRINT_LIST 1
  234.         fi
  235.         LIST=empty
  236.         FILTER_OPT=${FILTER_OPT%\ *\ *}
  237.         PARSE_OPT_CLI
  238.         PRINT_LIST
  239.         ;;
  240.     e|E)
  241.         read -p "Enter new file extension (current is \"$FTYPE\"): " FTYPE
  242.         if [ -z "$FTYPE" ]; then PRINT_LIST 1; fi
  243.         ERROR_MSG="No files with the new extension \"$FTYPE\" found"
  244.         BACKUP save
  245.         LIST=empty
  246.         PARSE_OPT_CLI
  247.         PRINT_LIST
  248.         ;;
  249.     s|S)
  250.         read -p "Enter new source path (current is \"$SOURCE\"): " NEW_PATH
  251.         if [ -z "$NEW_PATH" ]; then PRINT_LIST 1; fi
  252.         ERROR_MSG="New source \"$NEW_PATH\" doesn't contain any useful data"
  253.         GET_PATH "$NEW_PATH" 1
  254.         BACKUP save
  255.         LIST=empty
  256.         SOURCE=$NEW_PATH
  257.         PARSE_OPT_CLI
  258.         PRINT_LIST
  259.         ;;
  260.     t|T)
  261.         read -p "Enter new target path (current is \"$TARGET\"): " NEW_PATH
  262.         if [ -z "$NEW_PATH" ]; then PRINT_LIST 1; fi
  263.         GET_PATH "$NEW_PATH" 1
  264.         TARGET=$NEW_PATH
  265.         PRINT_LIST
  266.         ;;
  267.     r|R)
  268.         LIST=empty
  269.         FILTER_OPT=
  270.         FILTER nothing
  271.         PRINT_LIST
  272.         ;;
  273.     "")
  274.         exit
  275.         ;;
  276.     ?)
  277.         echo -e "\n\033[0;31mUnknown option: \"$OPT\" - try again!\033[0m"
  278.         PRINT_LIST
  279.         ;;
  280.     esac
  281. }
  282.  
  283. function PARSE_OPT_MENU() # parses new filter options set from the menu and calls CHECK_ARG() function
  284. {
  285.     for PART in $FILTER_OPT; do
  286.     if [ ! "$ARG" = set ]; then
  287.         OPTION=${PART#-*}
  288.         case $OPTION in
  289.         h|d|m|y|n)
  290.                 ARG=set
  291.                 ;;
  292.         ?)
  293.             echo -ne "\n\033[0;31mUnknown option: \"$OPTION\" - skipping filter treatment.\033[0m\n"
  294.             FILTER_OPT=$OLD_FILTER
  295.             PRINT_LIST
  296.             ;;
  297.         esac
  298.     else
  299.         ARG=$PART
  300.     fi
  301.     if [ ! "$ARG" = set ]; then CHECK_ARG $ARG $OPTION; fi
  302.     done
  303. }
  304.  
  305. function PARSE_OPT_CLI() # parses filter options from the command line and calls CHECK_ARG() function
  306. {
  307.     if [ -z "$FILTER_OPT" ]; then
  308.     FILTER nothing
  309.     else
  310.     for PART in $FILTER_OPT; do
  311.         if [ ! "$ARG" = set ]; then
  312.         OPTION=${PART#-*}
  313.             ARG=set
  314.         else
  315.         ARG=$PART
  316.         fi
  317.         if [ ! "$ARG" = set ]; then CHECK_ARG $ARG $OPTION; fi
  318.     done
  319.     fi
  320. }
  321.  
  322. while getopts :e:s:t:h:d:m:y:n: OPT; do
  323.     case $OPT in
  324.     e)
  325.         FTYPE=$OPTARG
  326.         if [[ ! $FTYPE = .* ]]; then FTYPE=.$FTYPE; fi
  327.         ;;
  328.     s)
  329.         GET_PATH "$OPTARG"
  330.         SOURCE=$NEW_PATH
  331.         ;;
  332.     t)
  333.         GET_PATH "$OPTARG"
  334.         TARGET=$NEW_PATH
  335.         ;;
  336.     h|d|m|y|n)
  337.         FILTER_OPT=$FILTER_OPT" -"$OPT" "$OPTARG
  338.         ;;
  339.     :)
  340.         ERROR $OPTARG" requires an argument."
  341.         ;;
  342.     ?)
  343.         ERROR "Unknown option: "\"$OPTARG\"
  344.         ;;
  345.     esac
  346. done
  347. STAT=check
  348. PARSE_OPT_CLI
  349. STAT=ok
  350. PARSE_OPT_CLI
  351. PRINT_LIST
  352. exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement