当列表来自 json 文件时,如何在 Python 中将整个列表作为命令行参数传递
How to pass an entire list as command line argument in Python when the list comes from a json file
根据 的回答之一,可以使用 nargs
成功传递列表。
但是,当实际从 json 文件中检索列表时,我不确定如何正确传递列表。所有的尝试都使 returns 始终是一个列表,我想知道如何从命令行成功地做到这一点(即不使用 json 在 python 脚本中进行解析)。
使用玩具示例的主要尝试(与上面提到的 post 非常相似)。
app_parsing_lists.py
import argparse
# defined command line options
# this also generates --help and error handling
CLI=argparse.ArgumentParser()
CLI.add_argument(
"--lista", # name on the CLI - drop the `--` for positional/required parameters
nargs="*", # 0 or more values expected => creates a list
type=str,
default=["1", "2", "3"], # default if nothing is provided
)
# parse the command line
args = CLI.parse_args()
# access CLI options
print("lista: %r" % args.lista)
file.json
{"field": [6, 7, 8]}
来自 CLI:
inlist=$(jq -r '.field | join(" ")' file.json)
python app_parsing_lists.py --lista $inlist
它打印 lista: ['6 7 8']
但想要的行为是 lista: ['6', '7', '8']
如何才能做到这一点?
简而言之:不要加入。
更具体地说:
$ python app_parsing_lists.py --lista $(echo '{"field": [6, 7, 8]}' | jq -r .field[])
lista: ['6', '7', '8']
总而言之:考虑这些例子,全部使用 %r
--
$ inlist=("4" "5" "6")
$ python app_parsing_lists.py --lista ${inlist[@]}
lista: ['4', '5', '6']
$ python app_parsing_lists.py --lista "${inlist[@]}"
lista: ['4', '5', '6']
$ python app_parsing_lists.py --lista $(jq -n '5,6,7')
lista: ['5', '6', '7']
$ inlist=($(jq -n '5,6,7'))
$ python app_parsing_lists.py --lista $inlist
lista: ['5']
$ python app_parsing_lists.py --lista "$inlist"
lista: ['5']
$ python app_parsing_lists.py --lista ${inlist[@]}
lista: ['5', '6', '7']
$
警告
如果任何列表项包含 space,则需要采用不同的方法,如下所示:
$ lista=("a b" 2 3)
$ for i in "${lista[@]}" ; do echo $i ; done
a b
2
3
$ python app_parsing_lists.py --lista "${lista[@]}"
lista: ['a b', '2', '3']
$ lista=($(echo '{"field": ["a b", 7, 8]}' | jq .field[]))
$ python app_parsing_lists.py --lista "${lista[@]}"
lista: ['"a', 'b"', '7', '8']
解决方案
unset lista
while IFS= read -r line ; do lista+=($line)
done < <(printf "%s\n" '{"field": ["a b", 7, 8]}' | jq -r .field[])
$ python app_parsing_lists.py --lista ${lista[@]}
lista: ['a b', '7', '8']
$
根据 nargs
成功传递列表。
但是,当实际从 json 文件中检索列表时,我不确定如何正确传递列表。所有的尝试都使 returns 始终是一个列表,我想知道如何从命令行成功地做到这一点(即不使用 json 在 python 脚本中进行解析)。
使用玩具示例的主要尝试(与上面提到的 post 非常相似)。
app_parsing_lists.py
import argparse
# defined command line options
# this also generates --help and error handling
CLI=argparse.ArgumentParser()
CLI.add_argument(
"--lista", # name on the CLI - drop the `--` for positional/required parameters
nargs="*", # 0 or more values expected => creates a list
type=str,
default=["1", "2", "3"], # default if nothing is provided
)
# parse the command line
args = CLI.parse_args()
# access CLI options
print("lista: %r" % args.lista)
file.json
{"field": [6, 7, 8]}
来自 CLI:
inlist=$(jq -r '.field | join(" ")' file.json)
python app_parsing_lists.py --lista $inlist
它打印 lista: ['6 7 8']
但想要的行为是 lista: ['6', '7', '8']
如何才能做到这一点?
简而言之:不要加入。
更具体地说:
$ python app_parsing_lists.py --lista $(echo '{"field": [6, 7, 8]}' | jq -r .field[])
lista: ['6', '7', '8']
总而言之:考虑这些例子,全部使用 %r
--
$ inlist=("4" "5" "6")
$ python app_parsing_lists.py --lista ${inlist[@]}
lista: ['4', '5', '6']
$ python app_parsing_lists.py --lista "${inlist[@]}"
lista: ['4', '5', '6']
$ python app_parsing_lists.py --lista $(jq -n '5,6,7')
lista: ['5', '6', '7']
$ inlist=($(jq -n '5,6,7'))
$ python app_parsing_lists.py --lista $inlist
lista: ['5']
$ python app_parsing_lists.py --lista "$inlist"
lista: ['5']
$ python app_parsing_lists.py --lista ${inlist[@]}
lista: ['5', '6', '7']
$
警告
如果任何列表项包含 space,则需要采用不同的方法,如下所示:
$ lista=("a b" 2 3)
$ for i in "${lista[@]}" ; do echo $i ; done
a b
2
3
$ python app_parsing_lists.py --lista "${lista[@]}"
lista: ['a b', '2', '3']
$ lista=($(echo '{"field": ["a b", 7, 8]}' | jq .field[]))
$ python app_parsing_lists.py --lista "${lista[@]}"
lista: ['"a', 'b"', '7', '8']
解决方案
unset lista
while IFS= read -r line ; do lista+=($line)
done < <(printf "%s\n" '{"field": ["a b", 7, 8]}' | jq -r .field[])
$ python app_parsing_lists.py --lista ${lista[@]}
lista: ['a b', '7', '8']
$