bash 如何在bash shell中将一个字符串拆分为多个变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10520623/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:02:18  来源:igfitidea点击:

How to split one string into multiple variables in bash shell?

bashshellvariables

提问by crunchybutternut

I've been looking for a solution and found similar questions, only they were attempting to split sentences with spaces between them, and the answers do not work for my situation.

我一直在寻找解决方案并发现了类似的问题,只是他们试图用空格分隔句子,而答案不适用于我的情况。

Currently a variable is being set to something a string like this:
ABCDE-123456
and I would like to split that into 2 variables, while eliminating the "-". i.e.:
var1=ABCDE
var2=123456

目前,一个变量被设置为这样的字符串:
ABCDE-123456
我想将其拆分为 2 个变量,同时消除“ -”。IE:
var1=ABCDE
var2=123456

How is it possible to accomplish this?

怎么可能做到这一点?



This is the solution that worked for me:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

这是对我有用的解决方案:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

Is it possible to use the cutcommand that will work without a delimiter (each character gets set as a variable)?

是否可以使用无需分隔符的cut命令(每个字符都设置为变量)?

var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.

var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.

采纳答案by Rob I

Ifyour solution doesn't have to be general, i.e. only needs to work for strings like your example, you could do:

如果您的解决方案不必是通用的,即只需要为您的示例那样的字符串工作,您可以这样做:

var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

I chose cuthere because you could simply extend the code for a few more variables...

我选择cut这里是因为您可以简单地为更多变量扩展代码......

回答by Paused until further notice.

readwith IFSare perfect for this:

readIFS是完美的:

$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo "$var1"
ABCDE
$ echo "$var2"
123456

Edit:

编辑:

Here is how you can read each individual character into array elements:

以下是如何将每个单独的字符读入数组元素:

$ read -a foo <<<"$(echo "ABCDE-123456" | sed 's/./& /g')"

Dump the array:

转储数组:

$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]="-" [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'

If there are spaces in the string:

如果字符串中有空格:

$ IFS=$'\v' read -a foo <<<"$(echo "ABCDE 123456" | sed 's/./&\v/g')"
$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]=" " [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'

回答by mkb

If you know it's going to be just two fields, you can skip the extra subprocesses like this:

如果您知道它将只有两个字段,您可以跳过额外的子流程,如下所示:

var1=${STR%-*}
var2=${STR#*-}

What does this do? ${STR%-*}deletes the shortest substring of $STRthat matches the pattern -*starting from the end of the string. ${STR#*-}does the same, but with the *-pattern and starting from the beginning of the string. They each have counterparts %%and ##which find the longestanchored pattern match. If anyone has a helpful mnemonic to remember which does which, let me know! I always have to try both to remember.

这有什么作用?从字符串的末尾开始${STR%-*}删除$STR与模式匹配的最短子-*字符串。${STR#*-}做同样的事情,但使用*-模式并从字符串的开头开始。它们每个都有对应物%%##并找到最长的锚定模式匹配。如果有人有一个有用的助记符来记住哪个是哪个,请告诉我!我总是必须尝试两者才能记住。

回答by tripleee

Sounds like a job for setwith a custom IFS.

听起来像是set定制的工作IFS

IFS=-
set $STR
var1=
var2=

(You will want to do this in a function with a local IFSso you don't mess up other parts of your script where you require IFSto be what you expect.)

(您将希望在带有 a 的函数中执行此操作,local IFS这样您就不会弄乱脚本的其他部分,您需要IFS满足您的期望。)

回答by anubhava

Using bash regex capabilities:

使用 bash 正则表达式功能:

re="^([^-]+)-(.*)$"
[[ "ABCDE-123456" =~ $re ]] && var1="${BASH_REMATCH[1]}" && var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2

OUTPUT

输出

ABCDE
123456