Необходим только один вызов jq. Чтобы выделить выходные данные для отдельных файлов, вы можете объединить этот один вызов с одним вызовом для awk или использовать цикл оболочки, как показано ниже.
Во-первых, вот иллюстрация того, как будет выглядеть конвейер оболочки:
jq -r --rawfile dd2name dd2name.tsv -f group.jq input.json |
while IFS=$'\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 можно легко скопировать из builtin.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. Если какое-либо из этих предположений нарушается, потребуется некоторая настройка.