Quick array assignment from command...

> On Tue, Mar 30, 2021 at 12:42:46PM -0400, Eric Cook wrote:
> > eval 'tags=('"${*@Q}"\)

On Tue, Mar 30, 2021 at 01:16:14PM -0400, Greg Wooledge wrote:
> declare -A tags=()
> while IFS=\| read -r tag value; do
>   tags[$tag]=$value
> done < <(exiftool ...)

As bash read loop could be something slow, I use (when I'm quiet about data
origin) something like:

  declare -A tags="($(
      sed -e 's/^\([^|]*\)|\?\(.*\)/[\1]="\2"/' < <(
         exiftool ...)) )"

Then
  declare -p tags
  declare -A tags=([Title]="A2 - Northern Lights" [Artist]="AK420" 
                   [Genre]="lofi" [Track]="" )

Note `|\?` in sed command will ensure EACH line would be ouput as `[LHS]="RHS"`
even if RHS is empty and pipe separator is missing.

But I have to confess: If not worst than using `eval`,
  I'm not absolutely sure about border effect and security issues.

Other sample, there is a quick `tcpstat` working on Linux:

    declare -a fds=(/proc/[1-9]*/fd/*)
    declare -a sockets="($(
    sed < <(ls -l  "${fds[@]}" 2>&1
        ) -ne 's@^.*proc/\([0-9]\+\)/.*socket:.\([0-9]\+\).@[\2]+="\1 "@p'))"
    while IFS=': ' read foo{,} port foo{,} mode foo{,,,,,,} node foo; do
        [ "$mode" = "0A" ] && [ "${sockets[node]}" ] &&
            while IFS= read -ru $lps line; do
                printf '%8d %s\n' 0x$port "$line"
              done {lps}< <(ps h ${sockets[node]})
    done < /proc/net/tcp

Where, when (not associative) array is declared as

    declare -a sockets=( [12345]+="1234 " [123]+="234 " [12345]+="456 " )

they hold:

    declare -p sockets
    declare -a sockets=([123]="234 " [12345]="1234 456 ")

-- 
 Félix Hauri  -  <fe...@f-hauri.ch>  -  http://www.f-hauri.ch

Reply via email to