Linux 在shell中,用点作为分隔符分割字符串的一部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19915452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In shell, split a portion of a string with dot as delimiter
提问by rodee
I am new to shell scripting, can you please help with below requirement, thanks.
我是 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
采纳答案by Mark Reed
First, note that you don't use $
when assigning to a parameter in the shell. Your first line should be just this:
首先,请注意$
在 shell 中分配参数时不要使用。你的第一行应该是这样的:
AU_NAME=AU_MSM3-3.7-00.01.02.03
Once you have that, then you can do something like this:
一旦你有了它,那么你可以做这样的事情:
IFS=. read major minor micro build <<EOF
${AU_NAME##*-}
EOF
where the ##*-
strips off everything from the beginning of the string through the last '-', leaving just "00.01.02.03", and the IFS (Internal Field Separator) variable tells the shell where to break the string into fields.
其中##*-
从字符串的开头到最后一个 '-' 去掉所有内容,只留下“00.01.02.03”,并且 IFS(内部字段分隔符)变量告诉 shell 在何处将字符串分解为字段。
In bash, zsh, and ksh93+, you can get that onto one line by shortening the here-document to a here-string:
在 bash、zsh 和 ksh93+ 中,您可以通过将 here-document 缩短为 here-string 来将其放到一行中:
IFS=. read major minor micro build <<<"${AU_NAME##*-}"
More generally, in those same shells (or any other shell that has arrays), you can split into an arbitrarily-sized array instead of distinct variables. This works in the given shells:
更一般地,在那些相同的 shell(或任何其他具有数组的 shell)中,您可以拆分为任意大小的数组而不是不同的变量。这适用于给定的外壳:
IFS=. components=(${AU_NAME##*-})
In older versions of ksh you can do this:
在旧版本的 ksh 中,您可以这样做:
IFS=. set -A components ${AU_NAME##*-}
That gets you this equivalence (except in zsh, which by default numbers the elements 1-4 instead of 0-3):
这让你得到这个等价(除了在 zsh 中,默认情况下元素编号为 1-4 而不是 0-3):
major=${components[0]}
minor=${components[1]}
micro=${components[2]}
build=${components[3]}
回答by paddy
In bash
, you can do something like this:
在 中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)
The grep
call uses -o
which outputs only the matching part of the line. The match itself is every non-hyphen character to the end of the line.
该grep
调用使用-o
which 只输出该行的匹配部分。匹配本身是行尾的每个非连字符字符。
The cut
command uses the delimeter .
(-d.
), and uses -f
to select individual fields.
该cut
命令使用分隔符.
( -d.
),并用于-f
选择单个字段。
It's a little clunky. I'm sure there are probably better ways to achieve this, but you can do quite a lot with grep
and cut
alone so they're handy tools to have in your arsenal.
它有点笨重。我敢肯定,有可能是更好的方式来实现这一点,但你可以做了很多与grep
和cut
单独所以他们得心应手的工具到您的阿森纳。
回答by choroba
You can use parameter expansion and the special IFS variable.
您可以使用参数扩展和特殊的 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]}
BTW, in an assignment, do not start the variable on the left hand side with a dollar sign.
顺便说一句,在赋值中,不要以美元符号开始左侧的变量。