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

Re: delimiters with more than one character? ...



On Tue, Jul 14, 2020 at 02:52:08PM +0200, Albretch Mueller wrote:
>  I have a string delimited by two characters: "\|"
> 
>  _S=" 34 + 45 \| abc \| 1 2 3 \| c\|123abc "
> 
>  which then I need to turn into a array looking like:
> 
>   _S_AR=(
> " 34 + 45 "
> " abc "
> " 1 2 3 "
> " c"
> "123abc "
> )
> 
>   I can't make awk or tr work in the way I need and all examples I
> have found use only one character.
> 
>   Is it possible to do such things in bash?

Not using shell builtin tools, no.  (Well, you could always iterate
over the string character by character

You can convince awk to do it, and produce a modified data stream
that bash can parse.

unicorn:~$ printf '%s\n' "$_S" | awk -F '\\\\[|]' '{for(i=1; i<=NF; i++) {printf("%s\0",$i)}}' | hd
00000000  20 33 34 20 2b 20 34 35  20 00 20 61 62 63 20 00  | 34 + 45 . abc .|
00000010  20 31 20 32 20 33 20 00  20 63 00 31 32 33 61 62  | 1 2 3 . c.123ab|
00000020  63 20 00                                          |c .|
00000023

So, there's our modified stream, with NUL delimiters.  Bash 4.4 and
above can read that directly into an array:

unicorn:~$ mapfile -t -d '' array < <(printf '%s\n' "$_S" | awk -F '\\\\[|]' '{for(i=1; i<=NF; i++) {printf("%s\0",$i)}}')
unicorn:~$ declare -p array
declare -a array=([0]=" 34 + 45 " [1]=" abc " [2]=" 1 2 3 " [3]=" c" [4]="123abc ")

With bash versions older than 4.4, mapfile does not have the -d ''
option, so you'd need a loop to populate an array from the NUL-delimited
stream.

There may be other ways, but this is the first one that came to mind.


Reply to: