Начиная с Python 2.7, по умолчанию включается pip. Просто загрузите нужный пакет через
python -m pip install [package-name]
Необходим только один вызов 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 можно использовать вместо приведенной выше команды while ... done
:
awk -F\\t 'fn && (fn!=$1) {close(fn)}; {fn=$1; print $2 >> fn}'
Если файл отображения dd2name.tsv не содержит суффикс ".txt", он может быть легко добавлен любым из множества способов, в зависимости от вкуса.
Отметим также, что предложенные решения выше делают некоторые предположения, в частности, что значения .jlo не содержат табуляции, новых строк или NUL. Если какое-либо из этих предположений будет нарушено, потребуется некоторая настройка.
Я бы сделал это за три прохода, отфильтровав массив с желаемым 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