1

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.

2
  • Do you have write access to the Python script? Commented May 3, 2021 at 1:40
  • Yes, I do have the write access to the python script. Commented May 3, 2021 at 9:53

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

Instead of while, you can do for list in "${main_list[@]}"; do ...
@Philippe, thank you for the comment, will add that for loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.