Parse multiple json files and output the match/hits against the regex with associated file names

Viewed 260

Currently, the cat command piped to jq helps me to parse multiple JSON files in my working directory and screen against the regex pattern matching email ids available in all in the files. However, am keen to identify the file name also in which the regex pattern is being hit/matched

cat *.json | jq '. as $data | [path(..| select(scalars and (tostring | test("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$", "ixn")))) ] | map({ (.|join(".")): (. as $path | .=$data | getpath($path)) }) | reduce .[] as $item ({}; . * $item)' 

Request your kind help tweaking the command to print $filename. thanks!

2 Answers

input_filename evaluates to the input file name of the file currently being read (after it has been opened). For STDIN, it evaluates to "<stdin>":

jq  'input_filename, input_filename' <<< 1
"<stdin>"
"<stdin>"

It works with the -n command-line option, but only after an input or inputs function has been called:

jq -n 'input_filename, (input | input_filename)' <<< 1
null
"<stdin>"

For a jq-internal solution use input_filename as @peak suggested. Here's an external solution which iterates over your input files and passes the file name as variable into jq. This approach, however, calls jq once for each input file (as opposed to your cat *.json | jq ... approach which has just one call), so you might run into performance issues when applied to a larger number of input files.

for f in *.json
do jq --arg f "$f" '. as $data | ... (use $f here) ...' "$f"
done
Related