yargs takes stdin (newline separated, for now) and executes a command on every single line individually, unlike xargs's behaviour to execute one command on the whole batch at once. (get it? X-args, Y-args. hah). I also used find's "-exec {} \;" command execution method because it is far more elegant. replacing all {} with stdin is much more versatile)
(this script used to be named "toeach", I'm still not decided on the proper name)
Code:
#!/bin/sh
IFS=$'\n'
function printhelp {
echo ""
echo "Usage: yargs [options] [command]"
echo " the first argument not flagged as an option (with - at the beginning) is recognized"
echo " as the beginning of the [command]."
echo " the string '{}' anywhere in [command] will be replaced by a line of standard input."
echo " the command will be executed one time for each line supplised in standard input."
echo " if no '{}' string is supplied, the line from standard input will be placed at the "
echo " end of the command."
echo " denote the end of the command by \; if desired"
echo ""
echo "Options:"
echo " -p --pretend print what WOULD be executed, but don't actually execute."
echo " -p --pretend output what WOULD be executed, but don't execute."
echo " -f --fork execute all commands in parellel instead of one-by-one"
echo " -h --help print help"
echo " -v --version print version"
}
function printversion {
echo "yargs - build and execute command lines from individual standard inputs"
echo "version 0.1, Copyright (C) 2010 Brandon Captain. released under the terms and conditions of the GPL v2.0"
}
if [ -z "$1" ]; then
printversion;
printhelp;
exit 0
fi
ASK=0;
PARALLEL=0;
START=0;
commandfound=0;
args=("$@")
for (( i=0; $i<$#; i++ ))
do
opt=${args[$i]}
if [[ "${opt:0:1}" != "-" && "$commandfound" != 1 ]] ; then
for (( ; $i<$#; i++ )) ; do
if [[ "${args[$i]}" == ";" ]] ; then
break;
fi
COMMAND[${#COMMAND[*]}]="${args[$i]}"
done
commandfound="1"
continue;
fi
let START=$START+${#opt}
if [ "$opt" = "-h" ] || [ "$opt" = "--help" ]; then
printversion;
printhelp;
exit 0
elif [ "$opt" = "-v" ] || [ "$opt" = "--version" ]; then
printversion;
exit 0
fi
if [ "$opt" = "-f" ] || [ "$opt" = "--fork" ]; then
PARALLEL=1;
continue;
fi
if [ "$opt" = "-p" ] || [ "$opt" = "--pretend" ]; then
ASK=1;
continue;
fi
echo "$opt is not a valid option"
exit 1
done
while read line; do
parts[${#parts[*]}]="$line"
done
for part in "${parts[@]}"; do
# BRACKETS_SUPPLIED="false";
#
# # replace {} with input
# # doesnt work perfectly
# unset COMMAND_TMP
# for (( l=0; $l<${#COMMAND[@]}; l++ )) ; do
# for (( m=0; $m<${#COMMAND[$l]}; m++ )) ; do
#
# if [[ "${COMMAND[$l]:$m:2}" == "{}" ]] ; then
# BRACKETS_SUPPLIED="true";
# str_head=${COMMAND[$l]:0:$m}
# COMMAND_TMP[$l]="$str_head""$part"
#
# let m=$m+1+${#part}
# else
# COMMAND_TMP[$l]="${COMMAND_TMP[$l]}""${COMMAND[$l]:$m:1}"
# fi
# done
# done
echo "${COMMAND[@]}" | grep '{}' 1> /dev/null 2>/dev/null
if [[ "$?" == "0" ]] ; then
for (( l=0; $l<${#COMMAND[@]}; l++ )) ; do
COMMAND_TMP[$l]=`echo "${COMMAND[$l]}" | sed 's/{}/'"$part"'/g'`
done
else
for (( l=0; $l<${#COMMAND[@]}; l++ )) ; do
COMMAND_TMP[$l]="${COMMAND[$l]}"
done
COMMAND_TMP[${#COMMAND_TMP}]="$part";
fi
if [ "$ASK" == "1" ]; then
echo $ex
continue
fi
if [ "$PARALLEL" == "1" ]; then
${COMMAND_TMP[@]} $ex &
else
${COMMAND_TMP[@]} $ex
fi
done
exit 0