为什么我的 jq / read / echo 管道会删除反斜杠?

Why does my jq / read / echo pipeline remove backslashes?

我正在尝试将一个大的 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

有什么建议吗?

您必须使用 -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: \"\"

-rread 一起使用几乎总是您想要的,而且实际上应该是默认行为。