可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm having trouble using the IFS to convert my string into an array. Here is what I have as my string:
"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!
So why does trying to set IFS to Space manually not work?
回答1:
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.
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.
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.
Probably the most correct way to go from a string to an array is to use read
. Many examples here.
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.
回答2:
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:
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.
回答3:
The default $IFS
is to use whitespace as the token separator, including tabs and newlines.
Try this:
echo "$IFS" | cat -vte
If you haven't changed $IFS
, the output should be:
^I$ $
That's a space, followed by a single tab: ^I
, and a newline - note that cat
is printing any newlines as $
.
And so your script excerpt should work without touching $IFS
.