给出以下json:
[
{"_id":{"$oid":"6d2"},"jlo":"ΕΙ AJSB","dd":"d5f"},
{"_id":{"$oid":"c6d3"},"jlo":"ΕΙ ALKSB","dd":"5d9"},
{"_id":{"$oid":"b0cc6d4"},"jlo":"ΕΙ AGHTSB","dd":"1b1"},
{"_id":{"$oid":"6d2"},"jlo":"ΕPOWΙ AJSB","dd":"d5f"},
{"_id":{"$oid":"c6d3"},"jlo":"ΕGTΙ ALKSB","dd":"5d9"},
{"_id":{"$oid":"b0cc6d4"},"jlo":"ΕLKΙ AGHTSB","dd":"1b1"}
]
我需要做的是在一个单独的文件中以ll元素的每个离散值输出ta的唯一值,该文件以一对一表示法命名,其中每个dd代码都替换为人类可读的表示法:
d5f:departmentone
5d9:departmentalt
1b1:departshort
所需的输出,以每行为单位,jlo的每个唯一值以及在每个dd元素中发现的次数,因此最终得到如下结果:
first file named departmentone.txt:
ΕΙ AJSB 1
ΕPOWΙ AJSB 1
second file named departmentalt.txt
ΕΙ ALKSB 1
ΕGTΙ ALKSB 1
third file named departshort.txt
ΕΙ AGHTSB 2
我已经尝试过使用map并减少group_by,sort_by,但效果却很差
答案 0 :(得分:1)
只需要一次调用jq。要将输出分配给单独的文件,可以将这一调用与对awk的单个调用结合使用,或者可以使用如下所示的shell循环。
首先,这是壳管道外观的说明:
jq -r --rawfile dd2name dd2name.tsv -f group.jq input.json |
while IFS=$'\t' read -r f v ; do echo "$v" >> "$f" ; done
这假定到文件名的映射在名为dd2name.tsv的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的绝佳时机。否则,可以很容易地从buildin.jq(google:builtin.jq "def INDEX"
)复制其def,或者您也可以将最后一行替换为:| 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。如果违反了任何这些假设,则需要进行一些调整。
答案 1 :(得分:0)
我将分三遍进行操作,用所需的dd
过滤数组并按jlo
分组,然后提取数组的第一(保证)项的jlo
及其长度:
map(select(.dd == "d5f")) | group_by(.jlo) | map("\(.[0].jlo) \(length)") | .[]
您可以try it here。
全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