[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: String to array
From: |
Greg Wooledge |
Subject: |
Re: String to array |
Date: |
Thu, 30 Sep 2021 09:48:13 -0400 |
On Thu, Sep 30, 2021 at 03:52:16PM +0300, Tapani Tarvainen wrote:
> Is there some simple way to convert a string into an array in bash,
> with each character as an array element?
A loop is the simple and obvious way.
> It can obviously be done with a loop, e.g.,
> [...]
> and of course those are good enough for all(?) practical purposes, but
> I started wondering if there's a way to do it without an explicit
> loop.
> So this is not a practical problem, but perhaps someone will
> find it an amusing exercise.
As I understand it, you're asking for "no explicit loops", and "no
forked processes". That restricts the choices quite substantially.
Are implicit loops allowed? I mean, they *must* be, right? There's
no way to do this without a loop being involved in *some* underlying
layer, hidden away in the bowels of the shell.
Here's a thing:
unicorn:~$ string=$'hi bye\twhy\n\e[;1'
unicorn:~$ n=${#string}; eval "printf -v re '(.)%.0s' {1..$n}"
unicorn:~$ [[ $string =~ $re ]] && declare -p BASH_REMATCH
declare -a BASH_REMATCH=([0]=$'hi bye\twhy\n\E[;1' [1]="h" [2]="i" [3]=" "
[4]="b" [5]="y" [6]="e" [7]=$'\t' [8]="w" [9]="h" [10]="y" [11]=$'\n'
[12]=$'\E' [13]="[" [14]=";" [15]="1")
The implicit loops here are in the brace expansion, in the printf command,
and probably in the regular expression matcher that builds up the
BASH_REMATCH array variable.
You can use "${BASH_REMATCH[@]:1}" or similar to use the resulting list.
Here are some ways that *don't* work, or at least that I couldn't get
to work:
1) mapfile -d 'any character'
There doesn't appear to be any way to let mapfile delimit the input
by "any character in this set". Its -d option only accepts one
character as an argument (or one byte -- I'm not sure which).
2) mapfile -t -d $'\xff' array <<< 'expand string with \xff after each char'
I couldn't find any sort of back-reference in ${parameter/pattern/string}
to act as a substitute for sed $'s/./&\xff/g' .
3) [[ $string =~ (.)* ]]
The (.) is only applied once, despite the closure * that follows it.
(.)+ didn't work either. That led to constructing the
(.)(.)(.)... pattern instead.
- String to array, Tapani Tarvainen, 2021/09/30
- Re: String to array, Leonid Isaev (ifax), 2021/09/30
- Re: String to array, Alex fxmbsw7 Ratchev, 2021/09/30
- Re: String to array,
Greg Wooledge <=
- Re: String to array, Tapani Tarvainen, 2021/09/30
- Re: String to array, Greg Wooledge, 2021/09/30
- Re: String to array, Greg Wooledge, 2021/09/30
- Re: String to array, Alex fxmbsw7 Ratchev, 2021/09/30
- Re: String to array, Greg Wooledge, 2021/09/30
- Re: String to array, Alex fxmbsw7 Ratchev, 2021/09/30