16

我是shell脚本的新手,请您帮忙解决以下要求,谢谢。

$AU_NAME=AU_MSM3-3.7-00.01.02.03
#separate the string after last "-", with "." as delimiter
#that is, separate "00.01.02.03" and print/save as below.
major=00
minor=01
micro=02
build=03
4

3 回答 3

25

$首先,请注意在分配给 shell 中的参数时不要使用。你的第一行应该是这样的:

AU_NAME=AU_MSM3-3.7-00.01.02.03

$用于获取分配后的参数值。后面的位$可以是花括号中的表达式,除了名称之外还有额外的东西,允许您对值执行各种操作。例如,您可以执行以下操作:

IFS=. read major minor micro build <<EOF
${AU_NAME##*-}
EOF

其中##*-从字符串的开头到最后一个'-'剥离了所有内容,只留下“00.01.02.03”,IFS(内部字段分隔符)参数告诉shell在哪里将字符串分成字段。

在 bash、zsh 和 ksh93+ 中,您可以通过将 here-document 缩短为 here-string 来将其放在一行中:

IFS=. read major minor micro build <<<"${AU_NAME##*-}"

更一般地说,在这些相同的 shell 中,您可以拆分为任意大小的数组而不是不同的变量:

IFS=. components=(${AU_NAME##*-})

(虽然这种语法在特别古老的 ksh 版本中不起作用;在它们中你必须这样做:

IFS=. set -A components ${AU_NAME##*-}

)

这让你得到这个等价(除了在 zsh 中,它默认为元素编号 1-4 而不是 0-3):

major=${components[0]}
minor=${components[1]}
micro=${components[2]}
build=${components[3]}
于 2013-11-11T21:05:22.437 回答
15

bash中,您可以执行以下操作:

version=$(echo $AU_NAME | grep -o '[^-]*$')
major=$(echo $version | cut -d. -f1)
minor=$(echo $version | cut -d. -f2)
micro=$(echo $version | cut -d. -f3)
build=$(echo $version | cut -d. -f4)

grep调用使用-owhich 仅输出该行的匹配部分。匹配本身是到行尾的每个非连字符。

cut命令使用分隔符.( -d.),并用于-f选择各个字段。

这有点笨拙。我确信可能有更好的方法来实现这一点,但是你可以单独做很多事情,grep所以cut它们是你的武器库中的方便工具。

于 2013-11-11T20:45:50.820 回答
3

您可以使用参数扩展和特殊的 IFS 变量。

#! /bin/bash
AU_NAME=AU_MSM3-3.7-00.01.02.03
IFS=. VER=(${AU_NAME##*-})
for i in {0..3} ; do
    echo ${VER[i]}
done

major=${VER[0]}
minor=${VER[1]}
micro=${VER[2]}
build=${VER[3]}

顺便说一句,在赋值中,不要以美元符号开始左侧的变量。

于 2013-11-11T21:04:52.177 回答