Почему мой конвейер jq / read / echo удаляет обратную косую черту? - PullRequest
1 голос
/ 22 марта 2020

Я пытаюсь разбить большой файл 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, но это не помогло.

Я использую версию jq, поставляемую CentOS 7:

[root@machine]$ jq --version
jq-1.6

Есть предложения?

1 Ответ

1 голос
/ 22 марта 2020

Вы должны использовать опцию -r, чтобы read:

while read -r line; do echo "$line" > temp/"$(date +%s%N)".json; done

Это предотвращает интерпретацию backsla sh escape.

И вы должны заключите в кавычки ваши переменные.

Обратите внимание на разницу:

$ read var <<< 'quoted quotes: \"\"'
$ echo "$var"
quoted quotes: ""
$ read -r var <<< 'quoted quotes: \"\"'
$ echo "$var"
quoted quotes: \"\"

Использование -r с read почти всегда то, что вы хотите, и действительно должно быть поведением по умолчанию.

...