JQ создать вывод во многих отдельных файлах

Начиная с Python 2.7, по умолчанию включается pip. Просто загрузите нужный пакет через

python -m pip install [package-name]
1
задан peak 16 January 2019 в 16:58
поделиться

2 ответа

Необходим только один вызов jq. Чтобы выделить выходные данные для отдельных файлов, вы можете объединить этот один вызов с одним вызовом для awk или использовать цикл оболочки, как показано ниже.

Во-первых, вот иллюстрация того, как будет выглядеть конвейер оболочки:

jq -r --rawfile dd2name dd2name.tsv -f group.jq input.json |
  while IFS= 

Это предполагает, что отображение имен файлов находится в файле TSV с именем dd2name.tsv, и что следующая программа jq находится в group.jq:

def dict:
  split("\n") | map(select(length>0) | split("\t"))
  | INDEX(.[0]) | map_values(.[1]);

($dd2name | dict) as $dict
| ($dict | keys_unsorted[]) as $dd
| map(select(.dd == $dd))
| group_by(.jlo)
| map("\($dict[$dd])\t\(.[0].jlo) \(length)")[]

Как следует из названия, функция dict создает словарь, дающий сопоставление значений .dd с именами файлов. Предполагается наличие INDEX. Если у вашего jq нет INDEX, то сейчас самое время обновить ваш jq; в противном случае его def можно легко скопировать из buildin.jq (google: builtin.jq "def INDEX"), или вы можете заменить последнюю строку на: | reduce .[] as $p ({}; .[$p[0]] = $p[1]);

решение на основе awk

Вызов awk можно использовать вместо приведенной выше команды while ... done:

awk -F\\t 'fn && (fn!=$1) {close(fn)}; {fn=$1; print $2 >> fn}'

Сезон по вкусу

Если файл отображения dd2name.tsv не содержит суффикс ".txt", он может быть легко добавлен любым из множества способов, в зависимости от вкуса.

Отметим также, что предложенные решения выше делают некоторые предположения, в частности, что значения .jlo не содержат табуляции, новых строк или NUL. Если какое-либо из этих предположений будет нарушено, потребуется некоторая настройка.

\t' read -r f v ; do echo "$v" >> "$f" ; done

Это предполагает, что отображение имен файлов находится в файле TSV с именем dd2name.tsv, и что следующая программа jq находится в group.jq:

def dict:
  split("\n") | map(select(length>0) | split("\t"))
  | INDEX(.[0]) | map_values(.[1]);

($dd2name | dict) as $dict
| ($dict | keys_unsorted[]) as $dd
| map(select(.dd == $dd))
| group_by(.jlo)
| map("\($dict[$dd])\t\(.[0].jlo) \(length)")[]

Как следует из названия, функция dict создает словарь, дающий сопоставление значений .dd с именами файлов. Предполагается наличие INDEX. Если у вашего jq нет INDEX, то сейчас самое время обновить ваш jq; в противном случае его def можно легко скопировать из buildin.jq (google: builtin.jq "def INDEX"), или вы можете заменить последнюю строку на: | reduce .[] as $p ({}; .[$p[0]] = $p[1]);

решение на основе awk

Вызов awk можно использовать вместо приведенной выше команды while ... done:

awk -F\\t 'fn && (fn!=$1) {close(fn)}; {fn=$1; print $2 >> fn}'

Сезон по вкусу

Если файл отображения dd2name.tsv не содержит суффикс ".txt", он может быть легко добавлен любым из множества способов, в зависимости от вкуса.

Отметим также, что предложенные решения выше делают некоторые предположения, в частности, что значения .jlo не содержат табуляции, новых строк или NUL. Если какое-либо из этих предположений будет нарушено, потребуется некоторая настройка.

0
ответ дан peak 16 January 2019 в 16:58
поделиться

Я бы сделал это за три прохода, отфильтровав массив с желаемым dd и сгруппировав по jlo, затем извлекая jlo из первого (гарантированного) элемента массива и его длину: [118 ]

map(select(.dd == "d5f")) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]

Вы можете попробовать здесь .

Полный запуск bash:

jq --arg dd d5f --raw-output 'map(select(.dd == $dd)) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]' yourJsonFile > departmentone.txt
jq --arg dd 5d9 --raw-output 'map(select(.dd == $dd)) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]' yourJsonFile > departmentalt.txt
jq --arg dd 1b1 --raw-output 'map(select(.dd == $dd)) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]' yourJsonFile > departmentshort.txt

Предположим, у вас есть файл с именем «mapping.txt» со следующим содержимым:

d5f:departmentone
5d9:departmentalt
1b1:departshort

Вы можете извлечь эти коды и метки для генерации файлы:

while IFS=: read -r code label; do
    jq --arg dd $code --raw-output 'map(select(.dd == $dd)) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]' yourJsonFile > "$label".txt
done < mapping.txt
0
ответ дан Aaron 16 January 2019 в 16:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: