简体   繁体   中英

Multilple csv files joining to json output?

Thanks in advance for your support.

I did some googling but nothing helped me.

I have two input csv files having one to many relationship (parent child).

How to create json ouput for each record in the master with child fields from those two files ? while googling, I can see samples that say 1 single csv file to json but not multiple.

Here is an example

Parent File Employee
emp_no emp_name
1001    jhon
1002    mike

Child file Reportees
emp_no master_emp_no  emp_name
1010   1001           x
1011   1001           y
1012   1001           z
1013   1002           A
1014   1002           B

I need a json object for each entry in Parent table that includes child table details of that parent

first json object ---->  1001,john,[1010 x,1011 y,1012 z]
second json object ---->  1002,john,[1013 A,1014 B]

Please advice.

Here is a solution using jq

If the file filter.jq contains

def parse:
  reduce ( inputs                     # reads input tsv files and returns object
         | {                          # {
            f:input_filename,         #   "parent": [["emp_no",...], ["1001", "jho...
            r:split("\t")             #   "child": [["emp_no","master_emp_no",...
           }                          # }
         | select(.r|length>0)) as $i
    {}
  ; .[$i.f] += [$i.r]
  )
;

def restructure:
  [                                   # converts [["emp_no", "emp_name"],
    .[0]    as $h                     #           ["1001", "jhon"], ["1002", "mike"]]
  | .[1:][] as $v                     #       to [{"emp_no":"1001","emp_name":"jhon"},
  | [   [$h, $v]                      #           {"emp_no":"1002","emp_name":"mike"}]
      | transpose[]
      | {key:.[0], value:.[1]}
    ] | from_entries
 ]
;

def format:
    .child as $c                      # constructs the final output
  | .parent                           # emp_no,emp_name,children
  | map(.children = (                 # 1001,jhon,["1010 x","1011 y","1012 z"]
            .emp_no as $e             # 1002,mike,["1013 A","1014 B"]
          | $c
          | map(select($e == .master_emp_no)
          | "\(.emp_no) \(.emp_name)")
          | tojson
        )
    )
  | (.[0] | keys_unsorted), .[]
  | join(",")
;

  parse
| map_values(restructure)
| format

the file parent contains tab-separated values

emp_no  emp_name
1001    jhon
1002    mike

and the file child contains tab-separated values

emp_no  master_emp_no   emp_name
1010    1001    x
1011    1001    y
1012    1001    z
1013    1002    A
1014    1002    B

then the command

jq -M -R -n -r -f filter.jq parent child    

will produce

emp_no,emp_name,children
1001,jhon,["1010 x","1011 y","1012 z"]
1002,mike,["1013 A","1014 B"]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM