help-bash
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]