質問

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.

役に立ちましたか?

解決 2

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.

他のヒント

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

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).

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.

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

Try with this:

args=$*

useful=${args#* }
useful=${useful#* }
useful=${useful% *}

Then you wlill get the interesting parameters in the $result variable.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top