关于bash:如何将字符串解析为变量?

How to parse a string into variables?

我知道如何用这个问题的方式把一个字符串解析成变量,例如

1
ABCDE-123456

变成:

1
2
var1=ABCDE
var2=123456

比如说,通过cut。我可以用一个脚本来完成,没问题。

但我有几十个脚本,它们都以相同的方式解析字符串/参数(相同的参数和变量,即相同的解析策略)。有时我需要对解析机制进行更改或添加变量。

当然,我可以对几十个脚本中的每一个都进行检查,并手动更改解析(即使只是复制和粘贴),但这会很冗长,而且更容易出错。

有没有一种模块化的方式来解析字符串/参数?

我曾想过编写一个脚本,将字符串/参数解析为变量,然后编写exports,但export命令不能从子级到父级工作(反之亦然)。


我认为您真正想要的是在一个脚本中编写函数,并将其包含在所有其他脚本中。您可以通过source.命令包含其他shell脚本。

例如,可以在parseString.sh中定义解析函数。

1
2
3
function parseString {
    ...
}

然后在你的其他剧本里

1
2
3
source parseString.sh
# now we can call parseString function
parseString abcde-12345


类似的事情可能会奏效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
parse_it () {
    SEP=${SEP--}
    string=$1
    names=${@:2}

    IFS="$SEP" read $names <<<"$string"
}

$ parse_it ABCDE-123456 var1 var2
$ echo"$var1"
ABCDE
$ echo"$var2"
123456
$ SEP=: parse_it"foo:bar:baz" id1 id2 id3
$ echo $id2
bar

第一个参数是要分析的字符串,其余参数是作为要设置的变量传递给read的变量名。(这里不引用EDOCX1[1]是有意的,因为我们将让shell将字符串拆分为多个单词,每个变量一个。有效的变量名仅由uu、字母和数字组成,因此不必担心不需要引用$names来进行分词或生成路径名。该函数假定字符串使用一个"-"分隔符,可以通过环境重写该分隔符。

对于更复杂的分析,您可能需要使用自定义正则表达式(bash4或更高版本,-g标志到declare所需):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
parse_it () {
    reg_ex=$1
    string=$2
    shift 2
    [[ $string =~ $reg_ex ]] || return
    i=1
    for name; do
        declare -g"$name=${BASH_REMATCH[i++]}"
    done
}

$ parse_it '(.*)-(.*):(.*)'"abc-123:xyz" id1 id2 id3
$ echo"$id2"
123