Bash如何删除或过滤带有值的参数?

问题描述 投票:0回答:2

我想创建一个BASH脚本,将另一个脚本或命令作为包装器调用。应该收集调用参数,但有一个例外。如何过滤特殊参数名称值对?

例如,当我用参数count X=$#调用第一个脚本时:

$ ./foo.sh -v --first val1 ... --argname 'value with spaces' ... --last val3

然后它应该使用新的参数计数X'=X-2调用第二个命令或脚本:

$ ./bar.sh -v --first val1 ... --last val3
bash shell
2个回答
2
投票

可能有理由希望在函数中进行删除,但是您的尝试似乎过于复杂以及不安全和不透明,因为它不仅仅过滤数组。

args=("$@")
for ((i=0; i<"${#args[@]}"; ++i)); do
    case ${args[i]} in
        --argname) unset args[i]; unset args[i+1]; break;;
    esac
done
./bar.sh "${args[@]}"

0
投票

我为foo.sh提出了这个解决方案:

#!/bin/bash

echo "executing foo.sh:"

function arg_remove ()
{
    local array=("${@:3}")

    for ((i=0; i<"${#array[@]}"; ++i)); do
        case ${array[i]} in
            "$2") unset array[i]; unset array[i+1]; break ;;
        esac
    done

    # clean up unset array indexes
    for i in "${!array[@]}"; do
        new_array+=( "${array[i]}" )
    done
    array=("${new_array[@]}")
    unset new_array

    # assign array outside function scope
    local -g "$1=(  )"
    eval ${1}='("${array[@]}")'
}

echo "arguments income :" "$@"
arg_remove ARG_PASS '--argname' "$@"
echo "arguments passed :" "${ARG_PASS[@]}"

./bar.sh "${ARG_PASS[@]}"

第二个输出测试脚本将只打印逐行bar.sh分组的所有传递的参数:

#!/bin/bash

echo "executing bar.sh:"

while [[ $# -gt 0 ]]
do
    key="$1"

    if [[ "$key" == --* ]]; then
        shift
        echo $key $1
    else
        echo $key
    fi
    shift
done

现在调用第一个脚本会导致:

$ ./foo.sh -v --first val1 --argname 'value with spaces' --last val3
executing foo.sh:
arguments income : -v --first val1 --argname value with spaces --last val3
arguments passed : -v --first val1 --last val3

executing bar.sh:
-v
--first val1
--last val3

您还可以简化代码并删除function arg_remove的分离并清理,这样您就可以获得foo_mini.sh的简约版本而无需eval

#!/bin/bash

args=("${@}")
filter="--argname"

for ((i=0; i<"${#args[@]}"; ++i)); do
    case ${args[i]} in
        "$filter") unset args[i]; unset args[i+1]; break ;;
    esac
done

./bar.sh "${args[@]}"
© www.soinside.com 2019 - 2024. All rights reserved.