For any POSIX shell (without using a temporary array): Dropping any instance of -f
followed by java8
, or of -fjava8
, from the list of positional parameters, while counting the number of such dropped options-with arguments in the variable found
.
skip=0 found=0
for arg do
case $1 in
-f)
if [ "$2" = java8 ]; then
skip=2
found=$(( found + 1 ))
fi
;;
-f*)
if [ "$1" = -fjava8 ]; then
skip=1
found=$(( found + 1 ))
fi
esac
if [ "$skip" -eq 0 ]; then
set -- "$@" "$1"
else
skip=$(( skip - 1 ))
fi
shift
done
if [ "$skip" -eq 1 ]; then
set -- "$@" -f
found=$(( found - 1 ))
fi
printf 'Args: %s\n' "$*"
printf 'Found = %d\n' "$found"
The above loop iterates as often as the initial number of positional parameters.
If the first positional parameter is -f
, the second positional parameter is tested to see whether it's java8
. If the test is true, then we need to skip these two arguments, so the skip
counter is set to 2. We also increment found
to indicate that we've found one more instance of -f java8
.
If the first positional parameter is -fjava8
, then we need to skip this single argument, so the skip
counter is set to 1. We also increment found
to indicate that we've found one more instance of -fjava8
(the same as finding -f java8
).
After the case
statement, we don't do anything other than decrement the skip
counter and shift
off the first positional parameter if skip
is non-zero. If skip
is zero, we move the first positional parameter to the end of the list before calling shift
, effectively allowing the arguments we keep to cycle back through the list while dropping the unwanted arguments.
Since we're using the list of positional parameters in a cyclic way, we would lose the last argument if it was -f
and the first argument was java8
. This is what the last if
statement protects against.
java8
or the two back-to-back arguments-f
andjava8
? At first you only mentionjava8
, but the code you have looks for the-f
option, and your example involves-f
andjava8
. I suppose you don't want to remove-f
if it's followed by any other argument?getopts
can be used to process options passed the standard way as incmd -f java8 arg1 arg2 arg3
,cmd -fjava8 -- arg1 arg2 arg3
. In standard option processing, you can't have options after non-options, so you can't usegetopts
to parse the options as seen in your example script invocation (unless you first remove those 2 arg1 arg2 before the first options before processing the first invocation ofgetopts
).ps
?