Compare commits

...

9 Commits

Author SHA1 Message Date
Martchus 793cb51522 Fix wrong expansion parameter 2023-04-28 22:35:45 +02:00
Martchus e763bb62aa Fix inconsistent indentation 2021-11-23 22:24:53 +01:00
Martchus 8dfc640679 Fix quoting 2019-02-15 21:28:52 +01:00
Martchus cbd7ef41cf Fix handling depth 2017-08-31 20:10:37 +02:00
Martchus e5fa14b68a Improve help 2017-01-20 22:36:44 +01:00
Martchus 1a1bfa7653 Improve README.md 2017-01-20 22:25:05 +01:00
Martchus c27ca57a88 Fix typo, check whether depth unsigned 2017-01-20 22:19:07 +01:00
Martchus 13c23b9898 Handle names with multiple subsequent whitespaces correctly 2017-01-12 21:40:26 +01:00
Martchus 310641ec25 minor changes 2016-04-04 23:34:41 +02:00
2 changed files with 64 additions and 64 deletions

View File

@ -39,8 +39,13 @@ music_lib_aac
```
Just run:
```
diriterator --base-dir "./music_lib_aac" --target-dir "./music_lib_aac" --filter ".*\.(mp3$)" --cmd "mkdir -p \"\$ITERATOR_TARGET_DIR\" && ffmpeg -i \"\$ITERATOR_FULL_PATH\" -c:a libfdk_aac -vbr 4 \"\$ITERATOR_TARGET_DIR/\$ITERATOR_FILE_NAME_WITHOUT_EXTENSION.m4a\"
diriterator \
--base-dir "./music_lib_mp3" --target-dir "./music_lib_aac" \
--filter ".*\.(mp3$)" \
--cmd "mkdir -p \"\$ITERATOR_TARGET_DIR\" && ffmpeg -i \"\$ITERATOR_FULL_PATH\" -c:a libfdk_aac -vbr 4 \"\$ITERATOR_TARGET_DIR/\$ITERATOR_FILE_NAME_WITHOUT_EXTENSION.m4a"
```
The repository PKGBUILDs (also on my GitHub page) contains files for building an Arch Linux package.
The repository [PKGBUILDs](https://github.com/Martchus/PKGBUILDs) contains
files for building an Arch Linux package.

View File

@ -1,28 +1,35 @@
#!/bin/sh
#!/bin/bash
# set shell options
set -e # abort on first error
shopt -s nullglob # allow filename patterns which match no files to expand to a null string, rather than themselves
shopt -s dotglob
# define queue
queue=()
function queueecho {
for item in "${queue[@]}"
do
echo $item
for item in "${queue[@]}"; do
echo "$item"
done
}
function queueexec {
queueecho | parallel "-j$parallelcount" --eta "eval {}"
}
function iteratedirs {
shopt -s nullglob # from doc: If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves.
for item in "$1/"*
do
if [ -d "$item" ]; then
if [[ $dept == none ]] || [ $currentlevel -lt $dept ]; then
iteratedirs "${item}" $(($2 + 1)) "${3}${item##*/}/"
local dir="$1"
local currentlevel="$2"
local current_rel_dir="$3"
for item in "$dir"/*; do
if [[ -d $item ]]; then
if [[ $depth == none ]] || [[ $currentlevel -lt $depth ]]; then
iteratedirs "${item}" $(($currentlevel + 1)) "${current_rel_dir}${item##*/}/"
fi
elif [ -f "$item" ]; then
if [[ $filter == "" ]] || [[ "$item" =~ $filter ]]; then
elif [[ -f $item ]]; then
if [[ ! $filter ]] || [[ $item =~ $filter ]]; then
name=${item##*/}
namewithoutextension=${name%.*}
queue+=("ITERATOR_FULL_PATH=\"$item\" ITERATOR_FILE_NAME=\"$name\" ITERATOR_FILE_NAME_WITHOUT_EXTENSION=\"$namewithoutextension\" ITERATOR_CURRENT_DIR=\"$1\" ITERATOR_CURRENT_REL_DIR=\"$3\" ITERATOR_BASE_DIR=\"$basedir\" ITERATOR_TARGET_DIR=\"$targetdir/$3\" \"$cmd\" $append")
iteratortargetdir=${targetdir}/${current_rel_dir}
#queue+=("ITERATOR_FULL_PATH=${item@Q} ITERATOR_FILE_NAME=${name@Q} ITERATOR_FILE_NAME_WITHOUT_EXTENSION=${namewithoutextension@Q} ITERATOR_CURRENT_DIR=${dir@Q} ITERATOR_CURRENT_REL_DIR=${current_rel_dir@Q} ITERATOR_BASE_DIR=${basedir@QQ} ITERATOR_TARGET_DIR=${iteratortargetdir@Q} ${cmd@Q} ${append@Q}")
queue+=("ITERATOR_FULL_PATH=${item@Q} ITERATOR_FILE_NAME=${name@Q} ITERATOR_FILE_NAME_WITHOUT_EXTENSION=${namewithoutextension@Q} ITERATOR_CURRENT_DIR=${dir@Q} ITERATOR_CURRENT_REL_DIR=${current_rel_dir@Q} ITERATOR_BASE_DIR=${basedir@Q} ITERATOR_TARGET_DIR=${iteratortargetdir@Q} ${cmd@Q} ${append@Q}")
else
echo "${bold}${blue}Info:${normal} ${bold}Skipping »$item«.${normal}"
fi
@ -39,54 +46,44 @@ blue=$(tput setaf 4)
bold=$(tput bold)
normal=$(tput sgr0)
# parse arguments
read=
# read arguments
argcount=0
append=
basedir=./
dept=none
cmd=
filter=
targetdir=
parallelcount=+0
noconfirm=false
read= argcount=0 append= basedir=. targetdir= depth=none cmd= filter= parallelcount=+0 noconfirm=
for arg in "$@"
do
if [[ "--base-dir" == $arg ]]; then
if [[ $arg == --base-dir ]]; then
read=basedir
elif [[ "--dept" == $arg ]]; then
read=dept
elif [[ "--cmd" == $arg ]]; then
elif [[ $arg == --depth ]]; then
read=depth
elif [[ $arg == --cmd ]]; then
read=cmd
elif [[ "--filter" == $arg ]]; then
elif [[ $arg == --filter ]]; then
read=filter
elif [[ "--args" == $arg ]]; then
elif [[ $arg == --args ]]; then
read=arguments
elif [[ "--parallel-count" == $arg ]]; then
elif [[ $arg == --parallel-count ]]; then
read=parallelcount
elif [[ "--target-dir" == $arg ]]; then
elif [[ $arg == --target-dir ]]; then
read=target
elif [[ "--no-confirm" == $arg ]]; then
elif [[ $arg == --no-confirm ]]; then
noconfirm=true
elif [[ "--help" == $arg ]]; then
elif [[ $arg == --help ]] || [[ $arg == -h ]]; then
echo "${bold}Runs a script for each file in a directory hierarchy using GNU parallel.${normal}
--base-dir the base directory (./ by default)
--target-dir the target directory (base directory by default)
--dept the maximal recursion dept (unlimited by default)
--cmd the command to be executed
--filter a regular expression to filter files, eg. ${bold}.*\.(mp4$)${normal}
--args the arguments to be passed to cmd
--no-confirm generated commands will be executed without prompt for confirmation
--parallel-count the maximal number of commands to be executed parallel
--base-dir base directory (current directory by default)
--target-dir target directory (base directory by default)
--depth maximal recursion depth (unlimited by default)
--cmd command to be executed
--filter regular expression to filter files, eg. ${bold}.*\.((mp4$)|(mp3$))${normal}
--args arguments to be passed to cmd
--no-confirm generated commands will be executed without prompt for confirmation
--parallel-count maximal number of commands to be executed parallel
${bold}The following environment variables will be set when running the script:${normal}
ITERATOR_FULL_PATH Path of the current file.
ITERATOR_FILE_NAME Full name of the current file.
ITERATOR_FILE_NAME_WITHOUT_EXTENSION Name of the current file without extension.
ITERATOR_CURRENT_DIR Path of the current directory.
ITERATOR_BASE_DIR Path of the base directory (specified using --base-dir).
ITERATOR_CURRENT_REL_DIR Path of the current directory (relative to the base directory).
ITERATOR_TARGET_DIR Path of the target directory for the current file (specified --target-dir + ITERATOR_CURRENT_REL_DIR).
ITERATOR_FULL_PATH current file path
ITERATOR_FILE_NAME current file name with extension
ITERATOR_FILE_NAME_WITHOUT_EXTENSION current file name without extension
ITERATOR_CURRENT_DIR current directory
ITERATOR_BASE_DIR base directory (specified using --base-dir)
ITERATOR_CURRENT_REL_DIR current directory (relative to the base directory)
ITERATOR_TARGET_DIR target directory for the current file
"
exit 0
else
@ -94,12 +91,12 @@ ITERATOR_TARGET_DIR Path of the target directory for the curre
append="$append \"$arg\""
elif [[ $read == basedir ]]; then
basedir=$arg
elif [[ $read == dept ]]; then
if ! [[ $arg =~ ^-?[0-9]+$ ]]; then
echo "${bold}${red}Error:${normal} ${bold}specified dept »$arg« is not a number.${normal}"
elif [[ $read == depth ]]; then
if ! [[ $arg =~ ^[0-9]+$ ]]; then
echo "${bold}${red}Error:${normal} ${bold}specified depth »$arg« is not an unsigned number.${normal}"
exit 1
fi
dept=$arg
depth=$arg
elif [[ $read == cmd ]]; then
cmd=$arg
elif [[ $read == filter ]]; then
@ -118,10 +115,8 @@ ITERATOR_TARGET_DIR Path of the target directory for the curre
fi
done
# validate specified arguments, use base directory as target directory if not specified
if [[ $targetdir == "" ]]; then
targetdir=$basedir
fi
if [[ $cmd == "" ]]; then
[[ $targetdir ]] || targetdir=$basedir
if [[ ! $cmd ]]; then
echo "${bold}${red}Error:${normal} ${bold}No command specified.${normal}"
exit 1
fi
@ -130,15 +125,15 @@ iteratedirs "$basedir" 0
if [[ ${#queue[@]} -ge 1 ]]; then
echo "${bold}Generated queue${normal}"
queueecho
if [[ $noconfirm == true ]]; then
if [[ $noconfirm ]]; then
queueexec
else
while true; do
read -p "${bold}Do you want to execute the commands [y/n]?${normal} " yn
read -p "${bold}Do you want to execute ${#queue[@]} commands [y/n]?${normal} " yn
case $yn in
[Yy]* ) queueexec; break;;
[Nn]* ) exit;;
* ) echo "${bold}Please answer yes or no.${normal}";;
[Yy]*) queueexec; break;;
[Nn]*) exit;;
*) echo "${bold}Please answer yes or no.${normal}";;
esac
done
fi