![识别是否存在并从 shell args 中删除特定参数](https://linux22.com/image/208162/%E8%AF%86%E5%88%AB%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E5%B9%B6%E4%BB%8E%20shell%20args%20%E4%B8%AD%E5%88%A0%E9%99%A4%E7%89%B9%E5%AE%9A%E5%8F%82%E6%95%B0.png)
我必须检查脚本的 shell 参数中是否存在特定参数“java8”,如果存在则将其删除。我还希望将其存储在其他变量中,但希望将其从我的 $* 中删除。
我尝试使用 getopts 检查 arg 是否存在,但我不知道如何删除 argument 。
请注意 - 检查“java8”的 arg 位置未知,我可以在任何地方
while getopts "f:" flag
do
case $flag in
f)
echo $OPTARG
;;
esac
done
echo $*
~
所以基本上当我调用时 -
./test.sh arg1 arg2 -f java8 arg3
执行 getopts 块后,剩余的参数将是
参数1、参数2、参数3
答案1
对于任何 POSIX shell(不使用临时数组):从位置参数列表中删除-f
后跟java8
或 的任何实例,同时计算此类删除选项的数量 - 参数包含在变量 中。-fjava8
found
skip=0 found=0
for arg do
case $1 in
-f)
if [ "$2" = java8 ]; then
skip=2
found=$(( found + 1 ))
fi
;;
-f*)
if [ "$1" = -fjava8 ]; then
skip=1
found=$(( found + 1 ))
fi
esac
if [ "$skip" -eq 0 ]; then
set -- "$@" "$1"
else
skip=$(( skip - 1 ))
fi
shift
done
if [ "$skip" -eq 1 ]; then
set -- "$@" -f
found=$(( found - 1 ))
fi
printf 'Args: %s\n' "$*"
printf 'Found = %d\n' "$found"
上述循环的迭代次数与位置参数的初始数量一样多。
如果第一个位置参数为-f
,则测试第二个位置参数是否为java8
。如果测试是真的,那么我们需要跳过这两个参数,因此计数器skip
设置为 2。我们还递增found
以表明我们又找到了 的一个实例-f java8
。
如果第一个位置参数是-fjava8
,那么我们需要跳过这个单个参数,因此计数器skip
设置为 1。我们还递增found
以指示我们又找到了 的一个实例-fjava8
(与find 相同-f java8
)。
在该语句之后,除了递减计数器并关闭第一个位置参数(如果非零)case
之外,我们不执行任何操作。如果为零,我们在调用之前将第一个位置参数移动到列表的末尾,从而有效地允许我们保留的参数在列表中循环返回,同时删除不需要的参数。skip
shift
skip
skip
shift
由于我们以循环方式使用位置参数列表,因此如果最后一个参数是-f
且第一个参数是 ,我们将丢失最后一个参数java8
。这就是最后一条if
语句所要防止的。
答案2
也许是这样的?我假设您想删除-f java8
...
#!/bin/bash
while (( $# )); do
if [[ $1 = "-f" ]] && [[ $2 = "java8" ]]; then
shift 2
continue
fi
args+=( "$1" )
shift
done
echo "${args[*]}"
用法示例:
$ ./argtest.sh one two three
one two three
$ ./argtest.sh one two -f java8 three four
one two three four
$ ./argtest.sh -f java8 -f foo -f bar
-f foo -f bar