zillur rahman
zillur rahman

Reputation: 395

access multiple output array of python in bash

I have a python script that print out 3 different lists. How can I access them. For example:

python out:
[1,2,3,4][a,b,c,d][p,q,r,s]

Now in bash I want to access them as:

list1=[1,2,3,4]
list2=[a,b,c,d]
list3=[p,q,r,s]

So far, I tried something like:

x=$(python myscript.py input.csv)

Now, If I use echo $x I can see the above mentioned list: [1,2,3,4][a,b,c,d][p,q,r,s] How could I get 3 different lists? Thanks for help.

Upvotes: 1

Views: 121

Answers (2)

Jetchisel
Jetchisel

Reputation: 7831

Here is one approach using bash.

#!/usr/bin/env bash

##: This line is a simple test that it works.
##: IFS='][' read -ra main_list <<< [1,2,3,4][a,b,c,d][p,q,r,s]

IFS='][' read -ra main_list < <(python myscript.py input.csv)

n=1
while read -r list; do
  [[ $list ]] || continue
  read -ra list$((n++)) <<< "${list//,/ }"
done < <(printf '%s\n' "${main_list[@]}")

declare -p list1 list2 list3

Output

declare -a list1=([0]="1" [1]="2" [2]="3" [3]="4")
declare -a list2=([0]="a" [1]="b" [2]="c" [3]="d")
declare -a list3=([0]="p" [1]="q" [2]="r" [3]="s")

As per Philippe's comment, a for loop is also an option.

IFS='][' read -ra main_list < <(python myscript.py input.csv)

n=1
for list in "${main_list[@]}"; do
  [[ $list ]] || continue
  read -ra list$((n++)) <<< "${list//,/ }"
done

declare -p list1 list2 list3

Upvotes: 0

jonathadv
jonathadv

Reputation: 356

The Python output does not match the bash syntax. If you can not print the bash syntax directly from the Python script you will need to parse the output first.

I suggest using the sed command for parsing the output into bash arrays:

echo $x | sed 's|,| |g; s|\[|list1=(|; s|\[|list2=(|; s|\[|list3=(|;s|\]|)\n|g;'

Command explanation

sed 's|,| |g;       # replaces `,` by blank space
     s|\[|list1=(|; # replaces the 1st `[` by `list1=(`
     s|\[|list2=(|; # replaces the 2nd `[` by `list2=(`
     s|\[|list3=(|; # replaces the 3rd `[` by `list3=(`
     s|\]|)\n|g;'   # replaces all `]` by `)`
     

The output would be something like:

list1=(1 2 3 4)
list2=(a b c d)
list3=(p q r s)

At this point, the output are not actual lists. To turn the output into bash commands, you can surround the whole command with eval $(...), then the output will be evaluated as a bash command.

Putting all together:

$ eval $(echo $x | sed 's|,| |g; s|\[|list1=(|; s|\[|list2=(|; s|\[|list3=(|;s|\]|)\n|g;')
$ echo ${list1[@]}
1 2 3 4
$ echo ${list2[@]}
a b c d
$ echo ${list3[@]}
p q r s

Upvotes: 1

Related Questions