为啥我的 jq / read / echo 管道会删除反斜杠?
Posted
技术标签:
【中文标题】为啥我的 jq / read / echo 管道会删除反斜杠?【英文标题】:Why does my jq / read / echo pipeline remove backslashes?为什么我的 jq / read / echo 管道会删除反斜杠? 【发布时间】:2020-07-02 18:32:01 【问题描述】:我正在尝试将一个大型 JSON 文件(约 4 个 Mio 元素)拆分为单独的文件(每个元素一个文件)。
文件有点像这样:
"books": [
"title": "Professional javascript - \"The best guide\"",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
,
"title": "Professional JavaScript",
"authors": [
"Nicholas C.Zakas"
],
"edition": 2,
"year": 2009
,
"title": "Professional Ajax",
"authors": [
"Nicholas C. Zakas",
"Jeremy McPeak",
"Joe Fawcett"
],
"edition": 2,
"year": 2008
]
要将每本书拆分为单独的文件,我使用以下命令:
cat books.json | jq -c -M '.books[]' | while read line; do echo $line > temp/$(date +%s%N).json; done
对于最后两项,一切正常,因为书名不包含任何引号。但是,在第一个中,\"
被 "
替换,这导致 JSON 文件损坏,因为后续解析器 - 当然 - 将 "
解释为元素的边界。
我尝试使用jq -r
,但没有帮助。
我使用的是 CentOS 7 自带的 jq 版本:
[root@machine]$ jq --version
jq-1.6
有什么建议吗?
【问题讨论】:
仅供参考,BashFAQ #1 中介绍了使用while read
循环的最佳实践。虽然它与jq
没有太大区别,但最好改掉使用cat filename | ...
的习惯;一些程序(包括sort
和tail
)在获得真实的、可查找的文件句柄而不是只能从前到后读取一次的 FIFO(又名管道)时可以运行得更快。
这能回答你的问题吗? sh read command eats slashes in input?
Why do backslashes disappear when run through echo
? 是另一个预先存在的候选副本(标题没有说清楚,但它是相同的 while read; do
错误)。
【参考方案1】:
你必须使用-r
选项来read
:
while read -r line; do echo "$line" > temp/"$(date +%s%N)".json; done
它可以防止解释反斜杠转义。
你应该引用你的变量。
看看区别:
$ read var <<< 'quoted quotes: \"\"'
$ echo "$var"
quoted quotes: ""
$ read -r var <<< 'quoted quotes: \"\"'
$ echo "$var"
quoted quotes: \"\"
将-r
与read
一起使用几乎总是您想要的,并且确实应该是默认行为。
【讨论】:
以上是关于为啥我的 jq / read / echo 管道会删除反斜杠?的主要内容,如果未能解决你的问题,请参考以下文章
为啥管道输入到“read”只有在输入“while read ...”结构时才有效? [复制]