1

I have a json file with thousands of lines and 90 json objects. Each object come with the following structure:

{
        "country_codes": [
            "GB"
        ],
        "institution_id": "ins_118309",
        "name": "Barclaycard (UK) - Online Banking: Personal", // I want to extract this line only
        "oauth": true,
        "products": [
            "assets",
            "auth",
            "balance",
            "transactions",
            "identity",
            "standing_orders"
        ],
        "routing_numbers": []
    },

For the ninety objects, I would like to delete all the lines and keep only the one with the name of the institution.

I guess that I will have to use a regex here? I'm happy to use with vim, sublime, vscode or any other code editor that will alow me to do so

How can I extract these lines so I will stay with the following 90 lines?

 "name": "Barclaycard (UK) - Online Banking: Personal",
 "name": "Metro Bank - Commercial and Business Online Plus",
 ...
 ...

 "name": "HSBC (UK) - Business",
mattb
  • 2,787
  • 2
  • 6
  • 20
Moyshe Zuchmir
  • 1,522
  • 12
  • 18
  • 1
    Assuming you aren't particular about the formatting, you should use something like `jq` to write the filtered objects to a new file, then replace the old with the new. – chepner Sep 12 '22 at 18:42
  • If you want to copy those lines, just do `:sort`, search for a known word `/Baclay`, yank `Vjjjjjy` and finally `u` to undo – balki Sep 29 '22 at 19:30

6 Answers6

3

If you must use a code editor, then in Vim you can delete all lines not matching a pattern with: :v/^\s*"name":/d

The above pattern says:

  • ^ line begins with
  • \s* zero or more white spaces
  • "name:" (pretty explanatory)

Although it's better to use a dedicated tool for parsing json files rather than regex as json is not a 'regular language'.

Bonus

If you do end up doing it in Vim, you can finish up by left align all the lines, do :%left or even just :%le.

mattb
  • 2,787
  • 2
  • 6
  • 20
2

That doesn't sound like the job for a text editor or even for regular expressions. How about using the right tool for the job™?

# print only the desired fields to stdout
$ jq '.[] | .name' < in.json

# write only the desired fields to file
$ jq '.[] | .name' < in.json > out.json

See https://stedolan.github.io/jq/.

If you really want to do it from a text editor, the simplest is still to filter the current buffer through a specialized external tool. In Vim, it would look like this:

:%!jq '.[] | .name'

See :help filter.


FWIW, here it is with another right tool for the job™:

:%!jj \\#.name -l

See https://github.com/tidwall/jj.

romainl
  • 186,200
  • 21
  • 280
  • 313
1

you can use grep eventually :

grep '^\s*"name":' your_file.json

mattb
  • 2,787
  • 2
  • 6
  • 20
Julien
  • 508
  • 2
  • 6
  • 13
0

In VSC

  • select institution_id
  • execute Selection > Select All Occurenses
  • Arrow Left
  • Ctrl+X
  • Esc
  • Ctrl+V
rioV8
  • 24,506
  • 3
  • 32
  • 49
0

In vscode (although I would think it is the same for any regex-handling editor), use this Find:

^(?!\s*"name":.*).*\n?|^\s*

and replace with nothing. See regex101 demo.

^(?!\s*"name":.*).*\n? : get all lines that are not followed by "name":... including the newline so that line is completely discarded.

^\s* gets the whitespace before "name":...... - also discarded since we are replacing all matches with nothing.

Mark
  • 143,421
  • 24
  • 428
  • 436
0

Parsing JSON in Vim natively:

call getline(1, '$')
    \ ->join("\n")
    \ ->json_decode()
    \ ->map({_, v -> printf('"name": "%s",', v.name)})
    \ ->append('$')

NB. Line continuation is only available when sourcing script from file. If run interactively then type command on a single line.

Matt
  • 13,674
  • 1
  • 18
  • 27