带有使 JQ 失败的控制代码的 AWS CLI returns JSON
AWS CLI returns JSON with control codes making JQ fail
我已经多次使用 jq
从 AWS CLI 返回的 JSON 中解析、选取值等,例如对于 ec2 describe-instances
等等
现在我正在使用 dockerized version of AWS CLI v2 获取 CloudWatch 日志组列表:
$ alias aws='docker run --rm -it -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli'
$ aws logs describe-log-groups
{
"logGroups": [
{
...
}
]
}
这看起来很合适JSON;然而,当将其传送到 jq
时,我得到:
parse error: Invalid numeric literal at line 1, column 2
如果在二进制编辑器中查看从 aws
返回的 JSON,或者使用 jq
:s inputs
功能,我发现它包含很多控制代码:
[
"\u001b[?1h\u001b=\r{\u001b[m\r",
" \"logGroups\": [\u001b[m\r",
" {\u001b[m\r",
" \"logGroupName\": \"/aws/lambda/...
...
在我看来,是我通过 docker 使用 AWS CLI 导致了这一点,因为当使用使用 pip
安装的老式 AWS CLI v1 时,它不会发生- 但它也可能是 v2 与 v1 的关键区别,而不是使用 docker 作为我猜的环境(我从未尝试过本地安装 v2)。
这些控制代码,例如\u001b[m
,看起来像 ANSI 代码来控制格式,例如粗体、颜色等。但是据我所知,AWS CLI 不使用 colored/ANSI 输出。为什么它们包含在返回的 JSON 中?是否有一个简单的工具可以去除它们,以便我可以继续使用 docker 化的 AWS CLI v2 并将输出通过管道传输到 jq
?我使用复杂的 sed
模式找到了其他答案,我心想一定有更简单的方法来做到这一点?
Edit:这是一个使用 xxd
显示控制代码的最小示例。我故意列出具有不匹配过滤器的日志组以获得空数组:
$ aws logs describe-log-groups --log-group-name-prefix FOO > foo.txt
$ xxd foo.txt
00000000: 1b5b 3f31 681b 3d0d 7b1b 5b6d 0d0a 2020 .[?1h.=.{.[m..
00000010: 2020 226c 6f67 4772 6f75 7073 223a 205b "logGroups": [
00000020: 5d1b 5b6d 0d0a 7d1b 5b6d 0d0a 0d1b 5b4b ].[m..}.[m....[K
00000030: 1b5b 3f31 6c1b 3e .[?1l.>
$ cat foo.txt | jq
parse error: Invalid numeric literal at line 1, column 2
$
使用非docker化的 AWS CLI v1 时 xxd
显示相同的内容:
00000000: 7b0a 2020 2020 226c 6f67 4772 6f75 7073 {. "logGroups
00000010: 223a 205b 5d0a 7d0a ": [].}.
aws
CLI 将其输出提供给 less
,因为 a) 您已经分配了一个带有 -it
标志的伪终端,b) 就进程而言关注的是,它直接输出到 tty 而不是管道,并且 c) 你没有 told it do anything else instead. The correct fix is to remove -it
- it's only there for when you need to provide interactive input,如果你将输出通过管道传输到 jq 那么你不需要或不想要交互式输入。但是,如果您尝试设置别名或函数以无缝代替 aws
,您需要根据是否需要交互式输入来决定是否传递 -it
。你可以试试这个:
function daws() {
local usetty
if [ -t 1 ]
then
usetty=-it
else
usetty=
fi
docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"
}
并且在一行中:
function daws() { local usetty; if [ -t 1 ]; then usetty=-it; else usetty=; fi; docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"; }
或者您可以传递 --no-cli-pager
或将环境变量 AWS_PAGER
设置为 cat
,但我都试过了,虽然它们没有导致任何错误,但仍有一些错误奇怪的混乱输出,其中换行符没有为部分输出应用回车-return。
我已经多次使用 jq
从 AWS CLI 返回的 JSON 中解析、选取值等,例如对于 ec2 describe-instances
等等
现在我正在使用 dockerized version of AWS CLI v2 获取 CloudWatch 日志组列表:
$ alias aws='docker run --rm -it -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli'
$ aws logs describe-log-groups
{
"logGroups": [
{
...
}
]
}
这看起来很合适JSON;然而,当将其传送到 jq
时,我得到:
parse error: Invalid numeric literal at line 1, column 2
如果在二进制编辑器中查看从 aws
返回的 JSON,或者使用 jq
:s inputs
功能,我发现它包含很多控制代码:
[
"\u001b[?1h\u001b=\r{\u001b[m\r",
" \"logGroups\": [\u001b[m\r",
" {\u001b[m\r",
" \"logGroupName\": \"/aws/lambda/...
...
在我看来,是我通过 docker 使用 AWS CLI 导致了这一点,因为当使用使用 pip
安装的老式 AWS CLI v1 时,它不会发生- 但它也可能是 v2 与 v1 的关键区别,而不是使用 docker 作为我猜的环境(我从未尝试过本地安装 v2)。
这些控制代码,例如\u001b[m
,看起来像 ANSI 代码来控制格式,例如粗体、颜色等。但是据我所知,AWS CLI 不使用 colored/ANSI 输出。为什么它们包含在返回的 JSON 中?是否有一个简单的工具可以去除它们,以便我可以继续使用 docker 化的 AWS CLI v2 并将输出通过管道传输到 jq
?我使用复杂的 sed
模式找到了其他答案,我心想一定有更简单的方法来做到这一点?
Edit:这是一个使用 xxd
显示控制代码的最小示例。我故意列出具有不匹配过滤器的日志组以获得空数组:
$ aws logs describe-log-groups --log-group-name-prefix FOO > foo.txt
$ xxd foo.txt
00000000: 1b5b 3f31 681b 3d0d 7b1b 5b6d 0d0a 2020 .[?1h.=.{.[m..
00000010: 2020 226c 6f67 4772 6f75 7073 223a 205b "logGroups": [
00000020: 5d1b 5b6d 0d0a 7d1b 5b6d 0d0a 0d1b 5b4b ].[m..}.[m....[K
00000030: 1b5b 3f31 6c1b 3e .[?1l.>
$ cat foo.txt | jq
parse error: Invalid numeric literal at line 1, column 2
$
使用非docker化的 AWS CLI v1 时 xxd
显示相同的内容:
00000000: 7b0a 2020 2020 226c 6f67 4772 6f75 7073 {. "logGroups
00000010: 223a 205b 5d0a 7d0a ": [].}.
aws
CLI 将其输出提供给 less
,因为 a) 您已经分配了一个带有 -it
标志的伪终端,b) 就进程而言关注的是,它直接输出到 tty 而不是管道,并且 c) 你没有 told it do anything else instead. The correct fix is to remove -it
- it's only there for when you need to provide interactive input,如果你将输出通过管道传输到 jq 那么你不需要或不想要交互式输入。但是,如果您尝试设置别名或函数以无缝代替 aws
,您需要根据是否需要交互式输入来决定是否传递 -it
。你可以试试这个:
function daws() {
local usetty
if [ -t 1 ]
then
usetty=-it
else
usetty=
fi
docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"
}
并且在一行中:
function daws() { local usetty; if [ -t 1 ]; then usetty=-it; else usetty=; fi; docker run --rm $usetty -v ~/.aws:/root/.aws -e AWS_PROFILE -e AWS_REGION amazon/aws-cli "$@"; }
或者您可以传递 --no-cli-pager
或将环境变量 AWS_PAGER
设置为 cat
,但我都试过了,虽然它们没有导致任何错误,但仍有一些错误奇怪的混乱输出,其中换行符没有为部分输出应用回车-return。