user797963
user797963

Reputation: 3027

Bash - remove one arg from a list of args

I'm having some trouble removing a single argument from a list of arguments.

This case is a little odd, because I need to set a variable that holds all ${@:2} args, parse them and set values, then remove any values from the variable holding the list of args if I find any args to be removed while parsing them.

example:

INARGS=${@:2}

for in in "${@:2}"
do
case $i in
    -f1)
         VAR1=1
         shift
     ;;
     -f2)
         VAR2=1
         shift
     ;;
     arbitrary_value)
         #
         #remove arbitrary_value from #INARGS
         #
         shift
     ;;
     *)
         shift
     ;; 
esace
done

echo $INARGS

So, if you were to run: './myscript mode -f1 value1 arbitrary_value -f2 value2', $INARGS would get 'f1 value1 -f2 value2' outputted, and 'arbitrary_value' would be removed.

I've tried a ton of different ways to do this, and I can't seem to get it right. Any help is much appreciated.

Upvotes: 0

Views: 1100

Answers (3)

SaintHax
SaintHax

Reputation: 1943

I removed the shift, b/c it doesn't work with your ${0:2}. You'd be shifting off the first arg, while you were processing the 2nd. You didn't state what this was for, so I've not tried to incorporate it. If you want to shift off everything but the last arg, then that works (but seems odd)

Instead you just need to reassign the INARG array with the argument masked out. Easy peasy.

var1=0; var2=0
INARGS=${@:2}

for i in "${@:2}"; do
   case $i in
      -f1) var1=1
         ;;
      -f2) var2=1
         ;;
      arbitrary_value)  # remove from INARGS
         declare -a INARGS=(${INARGS[@]/$i/})
         ;;
      *) true;;
   esac
done


echo "var1: $var1       var2: $var2"
echo "args: $@"
echo "array: ${INARGS[@]}"

If you do want to shift off all the args but the first, then you need to assign $1 to a variable (e.g. first_arg="$1", shift it off before the for loop, change the for loop to $@ instead, and finally... at the end do a set -- $first_arg to have only it remain.

Upvotes: 0

ams
ams

Reputation: 25589

It's easier to do this in an additive fashion, rather than subtractive:

INARGS=()

for in in "${@:2}"
do
case $i in
    -f1)
         VAR1=1
         INARGS+=("$i")
     ;;
     -f2)
         VAR2=1
         INARGS+=("$i")
     ;;
     arbitrary_value)
         #
         # leave INARGS alone here.
         #
     ;;
     *)
         INARGS+=("$i")
     ;; 
esac
done

echo $INARGS

Upvotes: 3

glenn jackman
glenn jackman

Reputation: 247002

You probably want something like this (untested)

mode=$1
shift

original_args=("$@")            # in case you need to refer to them later
args=()
while [[ $# -gt 0 ]]; do
    case $1 in
        -f1|-f2) args+=( "$1" "$2" ); shift 2 ;;
        *) shift ;;
    esac
done
echo "${args[@]}"

You'll want to do some research about how to use arrays in bash.

Upvotes: 1

Related Questions