Bash – Shell expansion and positional parameters

argumentsbash


I want to make an script equivalent to zgrep or bzgrep, but using tar.

I made two very similar attempts and I would like to know if there is a better one and if they could be improved or they are gonna crash for some reason I can't see. I know how use tar and bzip2, but I use to have some troubles with shell expansion.

First using $@:

#!/bin/bash
FILE_IN="${@: -1}"; ## Take last arg (file name) 
echo "FILE_IN: $FILE_IN"; 

INPUT_PARAMS="${@%%$FILE_IN}"; ## Take all args, but last (options and pattern)
echo "INPUT_PARAMS: $INPUT_PARAMS"; 

### Here I have to treat $INPUT_FILE before using grep (skipped) ###  

grep "$INPUT_PARAMS" "$FILE_IN"; 
exit $?; 

Second using variable (almost same above, just a couple of differences):

#!/bin/bash
ARGS="$@" 
FILE_IN="${!ARGS[@]: -1}"; ## Take last arg (file name) 

INPUT_PARAMS=${ARGS%%$FILE_IN};

### From here is identical 

They both seem to work, but then I took a look at script for bzgrep and it's much more complicated. So, it makes me think my scripts won't work.

Any thoughts? Can they be improved?

Best Answer

You need an array if you want to store more than one argument:

file_in="${@: -1}"
input_params=("${@:1:$#-1}")

Or:

file_in="${@: -1}"
input_params=("$@")
unset 'input_params[-1]'

Or, with just sh syntax:

n=$#
for file_in do
  shift
  [ "$((n = n - 1))" -gt 0 ] || break
  set -- "$@" "$file_in"
done
# input_params in "$@"

(all uppercase variables should be reserved for environment variables).

Related Question