【问题标题】:Get the next element in $@获取 $@ 中的下一个元素
【发布时间】:2022-01-11 14:26:49
【问题描述】:

我正在尝试像在 C 中一样解析 args:

if (str[i] == something && str[i + 1] == something) {
      //do somthing
}

我不知道怎么做str[i + 1]。这是我尝试过的:

for a in $@ ; do
        if [ $a == "create" ] && [sed 's/table/']; then
            echo "create database"
        fi
done

如果我找到createcreate 之后如果有database,我正在尝试做某事。

【问题讨论】:

标签: bash shell


【解决方案1】:

在 bash 中,我们可以使用间接变量来做同样的事情:

for ((i = 1, j = 2; i < $#; i++, j++)); do
    if [[ ${!i} == "create" && ${!j} == "database" ]]; then
        echo "create database"
        break
    fi
done

这种技术不会像shift 那样消耗参数。

参考:3.5.3 Shell Parameter Expansion第4段


关于您的代码的几点:

for a in $@ ; do
        if [ $a == "create" ] && [sed 's/table/']; then
            echo "create database"
        fi
done
  1. 始终引用 "$@" - 这是将 "arguments with whitespace" 保持在一起的唯一方法。
  2. 在 bash 中,使用 [[...]] 而不是 [...] -- 双括号形式对于不带引号的变量更安全。
  3. 括号不仅仅是语法,[ 是一个命令。对于外部命令,不要使用方括号:
    if [[ $a == "create" ]] && sed 's/table/other/' some_file; then
    
    在 bash 提示符下仔细阅读 help if

【讨论】:

    【解决方案2】:

    您可以在带有标志的循环中执行此操作,但执行此类操作的通常方法是在使用参数时转移它们。比如:

    #!/bin/sh
    
    while test $# -gt 0; do
        case $1 in
        create) shift; echo "arg after create is '$1'";;
        # ...
        esac
        shift
    done
    

    【讨论】:

    • 或者,您可以更改顺序并将参数称为$2,将轮班延迟到您使用它之后。
    【解决方案3】:

    你可以称之为作弊,但你可以将 $@ 放入数组 str 最初:

    str=( "$@" )
    i=... # Whatever you need
    if [[ ${str[$i]} == something && ${str[$((i+1))]} == something ]]
    then
      ....
    

    这是最接近的。但是,在实践中,重新考虑您的算法通常更方便,而不是弯曲一种语言以使其看起来与您已经熟悉的语言相似。

    【讨论】:

    • 是的,我重新考虑了,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 2011-07-03
    相关资源
    最近更新 更多