新手想学习bash和jq。我在 Windows 机器上,所以我想用 git bash 进行测试 - 我认为 git bash 与在 Linux 上运行的 bash 相同。
对于我的测试,我尝试将 JSON 中的列表提取到变量中。然而,我得到了(我认为的)奇怪的结果,所以我在 Docker 容器中的 Ubuntu 上尝试了相同的代码。 Ubuntu 给了我预期的结果。
左边是在 Docker 中运行的 Ubuntu。右侧是 git bash。有人可以解释为什么两个结果不同吗?
抱歉,正文如下:
乌班图:
root@ac88bd1c736e:/usr/local/bin# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS"
root@ac88bd1c736e:/usr/local/bin# jq --version
jq-1.6
root@ac88bd1c736e:/usr/local/bin# ls -la
total 20
drwxr-xr-x 1 root root 4096 Mar 8 16:48 .
drwxr-xr-x 1 root root 4096 Mar 1 02:03 ..
-rwxr-xr-x 1 root root 56 Jul 25 2022 service.py
-rwxr-xr-x 1 root root 96 Mar 7 18:21 test.json
root@ac88bd1c736e:/usr/local/bin# cat test.json
{
"foo": "bar",
"access": [
"rangers",
"avs"
],
"blah": {
"bizz": "buzz"
}
}root@ac88bd1c736e:/usr/local/bin# foo=`cat test.json | jq .access`
root@ac88bd1c736e:/usr/local/bin# echo $foo
[ "rangers", "avs" ]
root@ac88bd1c736e:/usr/local/bin#
git bash:
leehenry@PW03T2JD MINGW64 ~/..../bash
$ git --version
git version 2.39.2.windows.1
leehenry@PW03T2JD MINGW64 ~/..../bash
$ jq --version
jq-1.6
leehenry@PW03T2JD MINGW64 ~/..../bash
$ cat test.json
{
"foo": "bar",
"access": [
"rangers",
"avs"
],
"blah": {
"bizz": "buzz"
}
}
leehenry@PW03T2JD MINGW64 ~/..../bash
$ foo=`cat test.json | jq .access`
leehenry@PW03T2JD MINGW64 ~/..../bash
$ echo $foo
]avs"ers",
leehenry@PW03T2JD MINGW64 ~/..../bash
$
答案1
这是 CRLF 与 LF 行终止符的问题。
我希望
$ cat test.json | jq .access
看起来相当正常,每个输出 CR 都是不可见的,然后 LF 将我们带到下一行。
您可以通过以下方式验证
$ cat test.json | jq .access | hexdump -C
或者通过管道更紧凑地通过| hd
.请注意 0x0d CR 和 0x0a LF。
之后,apt install dos2unix
您可以通过管道传输 jq 的输出来修复它| dos2unix
,并根据需要使用 hexdump 进行验证。
联机bash
帮助页相当长。这里是具体的地方
$ foo=`cat test.json | jq .access`
绊倒了你。
命令替换...
Bash 通过以下方式执行扩展:用命令的标准输出替换命令替换,并删除所有尾随换行符。
因此,可以将其视为tr
删除了 LF,但保留了 CR。
另请注意此变量:
IFS
内部字段分隔符用于扩展后的字拆分以及使用 read 内置命令将行拆分为字。默认值为
<space><tab><newline>
。
Grep'ing for angle newline 揭示了更多出现这种情况的地方。
因此,如果您要要求bash
解析jq
包含 CR 的输出,您可能需要调整您的IFS
设置。
或者,选择更适合您需求的计算上下文。
十六进制转储 通常是 Ubuntu 的标准配置。
https://packages.ubuntu.com/jammy/amd64/bsdextrautils/filelist
如果丢失,您可以使用apt install bsdmainutils
它来将其拉入。