Issue
I would like to split $argv into two variables. One with opts and one with everything else.
function filter_opts
set -l filtered_opts
set -l new_argv
for opt in $argv
if string match -r -- '-.*' $opt
set -a filtered_opts $opt
else
set -a new_argv $opt
end
end
set -g argv $new_argv
echo $filtered_opts
end
function test_filter
set -g argv $argv
echo $argv
set -l opts (filter_opts $argv)
echo $opts
echo $argv
# prog1 $opts $argv
# prog2 $argv
end
But the output has the filtered opts duplicated and $argv isn't modified... :-(
$ test_filter Twilight Zone --test -t
Twilight Zone --test -t
--test -t --test -t
Twilight Zone --test -t
Ideally the output would look like this:
$ test_filter Twilight Zone --test -t
Twilight Zone --test -t
--test -t
Twilight Zone
Solution
Two improvements:
- It's not necessary to loop over
$argv
, you can just pass multiple arguments tostring filter
. - A function by default has its own scope, but you can have it modify its caller's scope via
--no-scope-shadowing
(see function docs)
Putting those ideas together:
function filter_opts --no-scope-shadowing
set options (string match -- '-*' $argv)
set arguments (string match --invert -- '-*' $argv)
end
function test_filter
filter_opts $argv
echo "Options: $options"
echo "Arguments: $arguments"
end
test_filter Twilight Zone --test -t
this outputs:
Options: --test -t
Arguments: Twilight Zone
also don't miss argparse
which is fish's argument parsing command.
Answered By - ridiculous_fish Answer Checked By - Mildred Charles (WPSolving Admin)