我正在尝试使用 Python 从一些 JSON 中提取信息(在我无法安装 jq 的系统上)。我当前的方法与 Why can't use semi-colon before for loop in Python? 中描述的语法限制相冲突.鉴于此限制,我如何修改此代码以使其仍然有效?
我当前的代码如下所示:
$ SHIFT=$(aws ec2 describe-images --region "$REGION" --filters "Name=tag:Release,Values=$RELEASE_CODE_1.2003.2")
$ echo "$SHIFT" | python -c "import sys, json; for image in json.load(sys.stdin)['Images']: print image['ImageId'];"
File "<string>", line 1
import sys, json; for image in json.load(sys.stdin)['Images']: print image['ImageId'];
^
SyntaxError: invalid syntax
由于 Python 的语法不允许使用分号将 for
循环与先前的命令分开,我该如何解决这个限制?
最佳答案
这里有几个选项:
将您的代码作为多行字符串传递。注意
"
用于分隔 Python 字符串而不是原始的'
此处为简单起见:A POSIX-compatible mechanism to embed a literal'
在单引号字符串中 is possible, but quite ugly .extractImageIds() { python -c ' import sys, json for image in json.load(sys.stdin)["Images"]: print image["ImageId"] ' "$@" }
使用 bash 的 C 风格转义字符串语法 (
$''
) 嵌入换行符,与$'\n'
一样.注意前导$
很关键,这不适用于/bin/sh
.参见 the bash-hackers' wiki on ANSI C-like strings了解详情。extractImageIds() { python -c $'import sys, json\nfor image in json.load(sys.stdin)["Images"]:\n\tprint image["ImageId"]' "$@"; }
使用
__import__()
以避免需要单独的import
命令。extractImageIds() { python -c 'for image in __import__("json").load(__import__("sys").stdin)["Images"]: print image["ImageId"]' "$@"; }
将代码传递到 stdin 并将输入移至 argv;请注意,这仅在输入不超过操作系统允许的最大命令行大小时才有效。考虑以下示例:
extractImageIds() { # capture function's input to a variable local input=$(</dev/stdin) || return # ...and expand that variable on the Python interpreter's command line python - "$input" "$@" <<'EOF' import sys, json for image in json.loads(sys.argv[1])["Images"]: print image["ImageId"] EOF }
请注意
$(</dev/stdin)
是$(cat)
的更高效的 bash-only 替代品;由于 shell 内置支持,它甚至可以在/dev/stdin
的操作系统上运行不作为文件存在。
所有这些都经过如下测试:
extractImageIds <<<'{"Images": [{"ImageId": "one"}, {"ImageId": "two"}]}'
要有效地从变量提供标准输入,可以运行 extractImageIds <<<"$variable"
反而。请注意 "$@"
包装器中的元素用于确保 sys.argv
填充了 shell 函数的参数——其中 sys.argv
未被正在运行的 Python 代码引用,此语法是可选的。
关于python - 如果需要循环和导入,如何将 Python 程序嵌入到 bash 命令中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48330855/