在shell中,用点作为分隔符拆分字符串的一部分

时间:2013-11-11 20:37:27

标签: linux shell

我是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

3 个答案:

答案 0 :(得分:16)

首先,请注意在分配给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(或任何其他具有数组的shell)中,您可以拆分为任意大小的数组而不是不同的变量。这适用于给定的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]}

答案 1 :(得分:9)

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调用使用-o,它只输出该行的匹配部分。匹配本身就是行尾的每个非连字符。

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

有点笨重。我确信可能有更好的方法来实现这一目标,但你可以单独使用grepcut做很多事情,这样他们就可以使用你的武器库。

答案 2 :(得分:2)

您可以使用参数扩展和特殊的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]}

顺便说一下,在作业中,不要在左侧用美元符号启动变量。