Reputation: 1767
I have something like that:
...
args=$*
echo $args
...
result is
unusable1 unusable2 useful useful ... useful unusable3
I need remove all "unusable" args. They always at first, second and last position.
After some investigation i find ${*:3}
bash syntax. It help remove first two.
...
args=${*:3}
echo $args
...
result is
useful useful ... useful unusable3
But I can't find how to remove last word using same nice syntax.
Upvotes: 5
Views: 6916
Reputation: 295989
args=${*:3}
flattens your argument list. You don't want to do that. Consider following the pattern given below instead:
# this next line sets "$@" for testing purposes; you don't need it in real life
set -- \
"first argument" \
"second argument" \
"third argument" \
"fourth argument" \
"fifth argument"
# trim the first two
args=( "${@:2}" )
# trim the last one
args=( "${args[@]:1:$(( ${#args[@]} - 2 ))}" )
# demonstrate the output content
printf '<%s>\n' "${args[@]}"
Running the above yields the following output:
<third argument>
<fourth argument>
...and, by doing so, demonstrates that it's correctly keeping arguments together, even when they contain spaces or wildcard characters.
For a shell completion script, you might also consider:
printf '%q ' "${args[@]}"
...which quotes content in such a way as to be eval'able by the shell.
Upvotes: 4
Reputation: 1065
Try with this:
args=$*
useful=${args#* }
useful=${useful#* }
useful=${useful% *}
Then you wlill get the interesting parameters in the $result
variable.
Upvotes: -1
Reputation: 1001
Using your syntax, you can use this :
args=${*:3:$#-3}
Explanation :
${*:offset:length}
offset is 3 to begin to the third argument and length is the number of arguments minus 3 (two first and last one).
Upvotes: 3
Reputation: 532478
bash
doesn't really provide such filtering methods for arrays. The best option is to just use a loop and filter one at a time.
for arg; do # Implicitly iterate over $@
[[ $arg =~ unusable ]] && continue
args+=( "$arg" )
done
Upvotes: 0
Reputation: 786319
You can use a function/script like this to print all but last arguments:
func() {
echo "${@:1:$#-1}";
}
func aa bb cc dd ee
aa bb cc dd
func foo bar baz hello how are you
foo bar baz hello how are
Upvotes: 6
Reputation: 158280
You could use awk
:
args="unusable1 unusable2 useful useful ... useful unusable3"
args=$(awk '{$1=$2=$NF="";print}' <<< "$args")
echo "$args"
Output:
useful useful ... useful
The command sets the the first, second and the last ($NF
) position to an empty string. NF
holds the number of fields in awk. Therefore $NF
is the last column.
Upvotes: 1