Altus
Altus

Reputation: 1435

Convert (in Bash) a Python list to a Bash array

I have a bash script that is calling a python script like so:

OUTPUT=$(python /path/path/script.py attr attr attr);

The python script will return a data list like so:

[item1, item2, item3]

How can I convert the $OUPUT variable which is a string of the return python data list into a bash array?

I'd like to read each item in bash if possible.

Upvotes: 22

Views: 23563

Answers (5)

mickours
mickours

Reputation: 1243

If you want to simply create a bash list from a python list in python, you can use this one-liner:

python -c 'print(" ".join([str(elem) for elem in [1, "l", 12]]))'

It gives you directly the list:

1 l 12

Note that it requires to modify the python code instead of doing this from the external bash code.

Upvotes: 1

chepner
chepner

Reputation: 532093

I would use a short Python wrapper to convert the string into something more parseable by bash.

# Proxy for script.py output that includes some potential bash pitfalls
python_output="['a b', 'c*', 6]"

# Let Python output each element of the list as a separate line;
# the only thing this cannot handle is multi-line elements; workarounds
# are possible, but not worth getting into unless necessary. 
while read -r; do
    OUTPUT+=("$REPLY")
done < <(python -c 'import ast, sys
print "\n".join(str(x) for x in ast.literal_eval(sys.argv[1]))
' "$python_output")

# Verify that each element was added to the array unscathed.
for e in "${OUTPUT[@]}"; do
    echo "$e"
done

In bash 4, you can use the readarray command to replace the while loop:

readarray -t OUTPUT < <(python -c ... )

Upvotes: 3

Cyrus
Cyrus

Reputation: 88839

Add () and | tr -d '[],':

OUTPUT=($(python /path/path/script.py attr attr attr | tr -d '[],'))

echo ${OUTPUT[0]}
echo ${OUTPUT[1]}
echo ${OUTPUT[2]}
echo ${OUTPUT[@]}

Output:

item1
item2
item3
item1 item2 item3

Upvotes: 43

l0b0
l0b0

Reputation: 58928

Bash declares arrays like this:

foo=(bar baz ban)

To convert space separated command output to an array you can therefore do this:

foo=($(my_command))

And to convert a list to a space separated string is very easy in Python:

' '.join(my_array)

If you print that instead of the list itself you can therefore trivially convert it to an array.

Upvotes: 4

alasimpara
alasimpara

Reputation: 195

You can make your script.py print a string that separates each item with spaces, which Bash will convert to an array, or you can use Bash to convert the return value of the python script into the format you want.

If you chose to print a string from your script.py you can use the following python code:

returnList = [1, 2, 3]
returnStr = ''
for item in returnList:
    returnStr += str(item)+' '
print(returnStr)

In this case, the output of the following bash script:

OUTPUT=$(python /path/to/script.py)
echo $OUTPUT
for i in $OUTPUT;
do
    echo $i
done

is:

1 2 3
1
2
3

Hope this helps you.

Upvotes: 9

Related Questions