[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: split a string into an array?
From: |
Koichi Murase |
Subject: |
Re: split a string into an array? |
Date: |
Fri, 11 Mar 2022 14:02:40 +0900 |
2022年3月11日(金) 13:07 Kerin Millar <kfm@plushkava.net>:
> You could do it this way instead:
>
> $ readarray -t -d $'\t' array < <(printf %s $'a\t\tb\tc')
> $ declare -p array
> declare -a array=([0]="a" [1]="" [2]="b" [3]="c")
> $ readarray -t -d $'\t' array < <(printf '')
> $ declare -p array
> declare -a array=()
There is still another corner case. The last empty element will be lost.
$ readarray -t -d $'\t' array < <(printf %s $'a\t')
$ declare -p array
declare -a array=([0]="a")
This can be solved by appending an extra separator in the input.
$ sep=$'\t' input=$'a\t'
$ mapfile -t -d "$sep" array < <(printf %s "$input${input:+$sep}")
--
I guess Peng is interested in a solution without forks. If so, we may
use the original code by Peng but with an additional check for the
empty input.
The original code still involves pipes (or temporary files in older
Bash or for a large input) by here strings. Instead, I usually do
something like
if [[ -o noglob ]]; then
IFS=$sep builtin eval 'array=($input${input:+sep})'
else
set -f
IFS=$sep builtin eval 'array=($input${input:+sep})'
set +f
fi
Note: "noglob / set -f" is needed to suppress unwanted pathname
expansions. "eval" is used to make IFS local to this command.
"builtin" is needed to make sure that the tempenv IFS doesn't remain
in the POSIX mode.
--
Koichi