string 使用 IFS 将字符串转换为数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11418502/
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
Bash string to array with IFS
提问by JDS
I'm having trouble using the IFS to convert my string into an array. Here is what I have as my string:
我在使用 IFS 将字符串转换为数组时遇到问题。这是我的字符串:
"Jun01 Jun02 Jun03 Jun04 Jun05 ..." #in that format, separated by spaces
And here is the code I have tried:
这是我尝试过的代码:
IFS=" " #set it to space character
DATES_ARRAY=($DATES_STRING) #from above
echo ${DATES_ARRAY[0]} #output is empty
However when I remove the IFS line it works. But I used a few lines to print out its default ASCII value and I got '32' which means 'Space' character. Being an OCD programmer I'd like to set it myself just to be safe... I don't know how it's going to be preset a priori!
但是,当我删除 IFS 行时,它可以工作。但是我用了几行来打印出它的默认 ASCII 值,我得到了“32”,这意味着“空格”字符。作为一名强迫症程序员,我想自己设置它只是为了安全......我不知道它会如何预先预设!
So why does trying to set IFS to Space manually not work?
那么为什么尝试手动将 IFS 设置为 Space 不起作用?
回答by ormaaj
It does work, but it's unnecessary anyway because space is guaranteed to be in IFS by default. Don't set it manually. Doing so can cause problems.
它确实有效,但无论如何都没有必要,因为默认情况下保证空间在 IFS 中。不要手动设置。这样做可能会导致问题。
Basically, never use word-splitting in Bash. Sometimes it's required to bite the bullet and use it if restricted to POSIX sh, if used very carefully. If you're going to set IFS, set it in the environment of one of the few commands where it has some effect, or at the very most, locally to a function.
基本上,永远不要在 Bash 中使用分词。有时需要硬着头皮使用它,如果仅限于 POSIX sh,如果使用得非常小心。如果您要设置 IFS,请将其设置在少数具有某种效果的命令之一的环境中,或者至多在函数的本地设置。
You'll never need to use this so I won't explain everything:
你永远不需要使用它,所以我不会解释一切:
$ printf -v str '%s ' Jun{01..10}
$ set -f
$ IFS=' ' declare -a 'arr=($str)'
$ declare -p arr
declare -a arr='([0]="Jun01" [1]="Jun02" [2]="Jun03" [3]="Jun04" [4]="Jun05" [5]="Jun06" [6]="Jun07" [7]="Jun08" [8]="Jun09" [9]="Jun10")'
IFS set to space here redundantly to show it works.
IFS 在这里冗余设置为空格以显示它的工作原理。
Probably the most correct way to go from a string to an array is to use read
. Many examples here.
从字符串到数组的最正确方法可能是使用read
. 这里有很多例子。
The cannonical method is:
规范方法是:
read -ra arr <<<"$str"
where IFS is optionally set in the environment of read
to act as a delimiter if it's something other than whitespace.
如果 IFSread
不是空格,则可以在环境中选择将 IFS 设置为分隔符。
回答by Dean Hall
I suggest not using $IFS
on its own to do word-splitting into an array, as setting and reverting $IFS is a pain. Use something like this:
我建议不要单独使用$IFS
将单词拆分为数组,因为设置和恢复 $IFS 是一种痛苦。使用这样的东西:
DATES_STRING='Jun01 Jun02 Jun03 Jun04 Jun05'
IFS=' ' read -a DATES_ARRAY <<< "$DATES_STRING"
I also suggest explicitly setting $IFS
in read
's environment so you're absolutely sure what it is.
我还建议明确设置$IFS
inread
的环境,以便您绝对确定它是什么。
回答by pb2q
The default $IFS
is to use whitespace as the token separator, including tabs and newlines.
默认$IFS
使用空格作为标记分隔符,包括制表符和换行符。
Try this:
尝试这个:
echo "$IFS" | cat -vte
If you haven't changed $IFS
, the output should be:
如果你没有改变$IFS
,输出应该是:
^I$
$
That's a space, followed by a single tab: ^I
, and a newline - note that cat
is printing any newlines as $
.
这是一个空格,后跟一个 tab:^I
和一个换行符 - 请注意,cat
将任何换行符打印为$
.
And so your script excerpt should work without touching $IFS
.
因此,您的脚本摘录应该可以在不接触$IFS
.