我的输入是命令,后跟无限数量的单字母选项,例如command -abc
。命令和选项都不带任何参数。我的目标是删除某些选项。
删除选项b
,c
作为示例,我可以这样实现:
$ cmd='command -abc'
$ pattern='(.*) -(.*)'
$ [[ $cmd =~ $pattern ]]
$ echo "${BASH_REMATCH[1]} -${BASH_REMATCH[2]//[cb]}"
command -a
然而,这仅适用于 bash。如何以兼容的方式解决这个问题,例如使用sed
and grep
?
答案1
假设该命令仅采用单字母选项,并且没有任何选项采用参数,我们可以创建一个包装脚本来解析命令行选项,删除不需要的选项并在给定新选项集的情况下执行命令:
#!/bin/sh
savedopts=-
printf 'Args in = %s\n' "$*"
while getopts :bc opt; do
case $opt in
b|c) ;; # nothing
*)
savedopts="$savedopts$OPTARG"
esac
done
shift "$(( OPTIND - 1 ))"
set -- "$savedopts" -- "$@"
printf 'Args out = %s\n' "$*"
# Run the command:
some-command "$@"
这会解析命令行,忽略选项b
和c
,并将其余选项放入$savedopts
。
$savedopts
然后用于运行包装的命令以及原始命令行上给出的任何操作数(用 分隔--
)。
getopts
即使我们要求它解析它可能不期望的选项,我们也不会收到任何错误。这是由于:
第一个参数中的初始getopts
。
测试运行:
$ ./script -abcd -b -c -- -bx -a foo bar
Args in = -abcd -b -c -- -bx -a foo bar
Args out = -ad -- -bx -a foo bar
./script: some-command: not found