Skip to content

Instantly share code, notes, and snippets.

@christhomas
Last active August 30, 2025 16:53
Show Gist options
  • Select an option

  • Save christhomas/d704f1e6b298faa3d5437e0f620d968d to your computer and use it in GitHub Desktop.

Select an option

Save christhomas/d704f1e6b298faa3d5437e0f620d968d to your computer and use it in GitHub Desktop.
Extract a subcommands arguments from a longer command full of other things that might also match
# Will take a command line and extract only the parts of the command line that are the arguments for a given subcommand
# I needed this to extract something similar to this
# ./bin/myprogram subcommand_a subcommand_b -a --bee -c -f subcommand_c --bee -f subcommand_d -f
# I needed the -a, --bee, -f
# Or if the user wrote this: -acf --bee or -ac --bee -f or combinations of single dashed parameters
# But I can't just search the command for -f, because -f is given to subcommand_[b/c/d] so a raw search might "find" the wrong -f argument
# Example, given the command: ./bin/myprogram subcommand_a subcommand_b -a --bee -c subcommand_c --bee -f subcommand_d -f
# Then searching for -f would find the -f from subcommand_c, but it was not given as an argument to subcommand_b
# So I wanted a function that would give me ONLY the arguments following a particular subcommand, ignoring similar arguments given to other subcommands that might follow later in the command string
# Usage: args=$(extract_subcommand_args "subcommand_b" $*)
# Given the above examples would return "-a --bee -c -f" or "-ac --bee -f" or "-acd --bee" etc etc.
# Then later in your program, you can use that string to search for whether this subcommand was given -a or -f for example
function extract_subcommand_args () {
local subcommand_token="$1"
shift
local args=("$@")
local found=0
local out=()
for ((i=0; i<${#args[@]}; i++)); do
if [[ $found -eq 0 && "${args[$i]}" == "$subcommand_token" ]]; then
found=1
continue
fi
if [[ $found -eq 1 ]]; then
if [[ "${args[$i]}" == --* || ( "${args[$i]}" == -* && "${args[$i]}" != "-" ) ]]; then
out+=("${args[$i]}")
else
break
fi
fi
done
echo "${out[@]}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment