在shell中,用点作为分隔符分割字符串的一部分[重复]

Posted

技术标签:

【中文标题】在shell中,用点作为分隔符分割字符串的一部分[重复]【英文标题】:In shell, split a portion of a string with dot as delimiter [duplicate] 【发布时间】:2013-11-23 19:00:13 【问题描述】:

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

【问题讨论】:

【参考方案1】:

首先,请注意,在分配给 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]

【讨论】:

【参考方案2】:

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 做很多事情,因此它们是您的武器库中的便捷工具。

【讨论】:

【参考方案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]

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

【讨论】:

以上是关于在shell中,用点作为分隔符分割字符串的一部分[重复]的主要内容,如果未能解决你的问题,请参考以下文章

编shell脚本遇到一个问题,awk能切割掉最后一个字段的值嘛?

shell中的数组操作

shell中的数组操作

linux shell 中 awk 分隔符

shell 特殊字符

shell特殊符号