help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: String to array


From: Alex fxmbsw7 Ratchev
Subject: Re: String to array
Date: Thu, 30 Sep 2021 15:49:04 +0200

at a second try with awk, the spawn awk once per str works, but the coproc
doesnt
im not sure why maybe someone knows

ive choosen awk for speed
s=ab34 ; awksplit() { gawk -v FS= -v RS=\\0 -v ORS=\\0 -e '{ gsub( /./,
"\\\\& " ) ; print }' "$@" ; } ; declare -a "one=( $( awksplit <<<"$s" -v
ORS= ) )" ; declare -p one  ; [[ ! -v ser ]] && coproc ser { awksplit ; } ;
ser() { printf %s\\0 "${@:2}" >&${ser[1]} ; declare -ga "$1=( $( <
/proc/fd/$ser ) )" ; declare -p $1 ; } ; ser serial "$s"

declare -a one=([0]="a" [1]="b" [2]="3" [3]="4")
[1] 17511
bash: /proc/fd/57: No such file or directory
declare -a serial=()


On Thu, Sep 30, 2021, 15:10 Alex fxmbsw7 Ratchev <fxmbsw7@gmail.com> wrote:

> you may get success accessing str via ${str:<position>:1}
>
> s=ab34 i=-1 e=${#s} r= ; while (( n = ++i + 1 <= e )) ; do r+="pos $n char
> ${s:i:1}|" ; done ; printf %s\\n "${r%|}"
>
> pos 1 char a|pos 1 char b|pos 1 char 3|pos 1 char 4
>
> $n is a bug of 1 but you may get the point
>
> a toarray id code a coproc awk to declare array, another mail with this
> may follow
>
> On Thu, Sep 30, 2021, 14:52 Tapani Tarvainen <bash@tapanitarvainen.fi>
> wrote:
>
>> Is there some simple way to convert a string into an array in bash,
>> with each character as an array element?
>>
>> It can obviously be done with a loop, e.g.,
>>
>> array=()
>> while [ -n "$string" ]
>> do
>>    array+=("${string:0:1}")
>>    string=${string:1}
>> done
>>
>> or, preserving the original string,
>>
>> array=()
>> i=0
>> while (( i < ${#string} ))
>> do
>>    array+=("${string:$((i++)):1}")
>> done
>>
>> 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.
>>
>> Here's my first idea:
>>
>> array=($(sed 's/./& /g' <<<$string))
>>
>> That sort of works, but it forks an extra process (sed) and loses
>> whitespace and breaks in interesting ways with any number of special
>> characters like *.
>>
>> This fixes most of those problems:
>>
>> fopt=${-//[!f]}
>> set -f
>> OLDIFS=$IFS
>> IFS=$'\n'
>> array=($(sed 's/./&\n/g' <<<$string))
>> IFS=$OLDIFS
>> set ${fopt:+-}${fopt:-+f}
>>
>> but it still loses newlines in the string and is harder to understand
>> and indeed even longer than the loops above - and it still calls sed,
>> and I'd like to do this with shell builtins only.
>>
>> (Side question: is there a better way to restore set -f/+f?)
>>
>> Playing a little with brace expansion I came up with this:
>>
>> eval tmparray=('\"\${string:'{0..$((${#string}-1))}':1}\"')
>> eval array=(${tmparray[@]})
>>
>> That works, but... let's just say it might be useful in some code
>> confuscation contest, hardly otherwise.
>>
>> But I can't shake the feeling that there should be some simple and
>> pretty way to do it with some such construct. Or at least something
>> simpler than that double eval thing. Especially since the reverse
>> operation is so simple:
>>
>> OLDIFS=$IFS
>> IFS=
>> string=${array[*]}
>> IFS=$OLDIFS
>>
>> Ideas?
>>
>> --
>> Tapani Tarvainen
>>
>>


reply via email to

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