Чтение файлов в JSON

Я хочу прочитать несколько файлов (index.html, style.css, main.js), чтобы создать полезную нагрузку JSON для загрузки.

Я знаю, что с nodejs я могу начать создавать то, что хочу, вот так:

var fs = require('fs');
fs.readFile('index.html', 'utf8', function (err, data) {
  if (err) throw err;
  out = JSON.stringify({"html": data});
  console.log(out);
});

Но как мне это сделать с jq?


person hendry    schedule 27.10.2015    source источник


Ответы (3)


Один из способов обработки нескольких текстовых файлов иллюстрируется следующим:

(jq -Rs . a.txt ; jq -sR . b.txt) | jq -s
[
  "1\n2\n",
  "3\n4\n"
]

Итак, в вашем случае вы бы сделали что-то вроде этого:

(jq -Rs '{ html: . }' index.html; \
 jq -Rs '{ javascript: . }' main.js; \
 jq -Rs '{ css: . }' style.css) |\
 jq -s add

То есть конвертировать каждый текстовый файл в строку JSON отдельно, а затем передавать эти строки в jq. Это имеет то преимущество, что не требует jq 1.5, но если у вас есть jq 1.5, то решение с использованием фильтра inputs может быть предпочтительнее.

person peak    schedule 27.10.2015
comment
Закрывать! Не могли бы вы изменить свой ответ на (jq -Rs '{ html: . }' index.html; jq -Rs '{ javascript: . }' main.js; jq -Rs '{ css: . }' style.css) | jq -s add? Это то, что я нашел, работает для меня. - person hendry; 28.10.2015

Это должно сработать для вас (требуется jq 1.5):

jq --null-input --raw-input \
  'reduce inputs as $line ({}; .[input_filename] += [$line]) | map_values(join("\n"))' \
  index.html style.css main.js

Вот фильтр сам по себе. Это довольно просто:

reduce inputs as $line ({}; .[input_filename] += [$line])
| map_values(join("\n"))

Пример:

$ cat test1.txt
foo
bar
baz

$ cat test2.txt
qux
quux
quuux

$ jq --null-input --raw-input \
  'reduce inputs as $line ({}; .[input_filename] += [$line]) | map_values(join("\n"))' \
  test1.txt test2.txt
{
  "test1.txt": "foo\nbar\nbaz",
  "test2.txt": "qux\nquux\nquuux"
}

P.S. Если вы не возражаете против новой строки в конце, вы можете сделать это вместо этого:

reduce inputs as $line ({}; .[input_filename] += "\($line)\n")
person Jordan Running    schedule 27.10.2015

Используйте параметр командной строки необработанного ввода (-R), чтобы прочитать ввод в виде строки. Затем вы можете создать свой результат json. Вы также захотите использовать его (-s) для многострочных текстовых файлов.

$ jq -Rs '{ html: . }' index.html

Однако это работает только для текстовых файлов. Если у вас есть двоичные файлы, вам придется сначала закодировать их. Вы можете использовать base64 для этого.

$ base64 -w0 image.jpg | jq -R '{ jpg: . }'
person Jeff Mercado    schedule 27.10.2015
comment
Это не выглядит правильно. s.natalian.org/2015-10-27/1445930412_1912x1036.png Также интересно сделать это для нескольких файлов. - person hendry; 27.10.2015
comment
Ну, это двоичный файл, вам нужно сначала его закодировать. - person Jeff Mercado; 27.10.2015
comment
Slurp действительно нужен, но как он работает с дополнительными файлами? например jq -Rs '{ html: ., js .}' index.html main.js не работает. - person hendry; 27.10.2015
comment
@peak: Ах, да, для многострочных текстовых файлов. Спасибо. - person Jeff Mercado; 27.10.2015
comment
@hendry: jq не очень подходит для объединения нескольких файлов. В какой-то степени это возможно для определенных вещей, но на самом деле он не масштабируется, чтобы делать гораздо больше, чем несколько. У вас есть более полный пример типов файлов, которые вы хотите объединить, и того, как вы хотите их объединить? То, о чем вы просите, может быть возможно без дополнительных внешних инструментов, но способы работы с каждым типом будут различаться. - person Jeff Mercado; 27.10.2015