1

I have a Perl (.pm) file that I've been trying to get into a JSON representation so that I can then search for keywords inside of it.

The directory for my script is /Devices/bin/script.py. The directory where the .pm file lives in one level up, so /Devices/Devices.PM. Devices.PM is just a static file containing data structured as dictionaries and lists like so:

mylist = (
    blah => {
        other       =9,
        houses       => 1,
        etc => [
            {   etc   => '5',
                ppl      => '3,
                things       => "etc",
                animals => [ 'blah-228', 'blah-229' ]
            },
            {   etc   => '9',
                ppl      => '5',
                things       => "22",
                animals => [ 'blah-2', 'blah-5' ]
            },
        ],
        partner => 'ets',
        location => 'wherever',
    },
    blah => {
        ppl => 6,
        place => 101,
        things => 'etc',
        animals => 'whatever',
    },

I have:

os.chdir("..")
with open('Devices.pm', 'r') as f:
    json_obj = json.dumps(f)
    print json_obj

but I keep getting TypeError: <open file 'SwitchConfig.pm', mode 'w' at 0x10c1f69c0> is not JSON serializable. I have tried this several ways with no luck, including json.dump(s). I keep getting different errors. Am I not understanding my .pm file structure correctly in order to turn it into a JSON representation?

2
  • seems related to this question Python No JSON object could be decoded, maybe try copying the file contents into something like jsonlist.com's validator and adjust as necessary Commented Apr 20, 2017 at 18:36
  • In python 3, you need to read the file f.read() Commented Apr 20, 2017 at 18:39

2 Answers 2

4

It seems that you need to read this with a Perl script (or one-liner) and so export proper JSON.

First, what is shown is not valid Perl. I'll assume typos in posting for some basic syntax errors.

There is also a missing % in front of mylist; in Perl variable names start with a sigil, % for hashes. I'll assume that it is an omission in posting but that it is there. If not, you'd have to fix that.

Let me then use a file data.pm such as

%mylist = ( 
    blah => { 
        other  => 9, 
        houses => 1,
        etc    => [ { etc => '5', ppl => '3' }, { etc => '9', ppl => '5' } ]
    }
);

which is a short sample of posted data, with a few typos fixed.

Here is a Perl script to make JSON from it. It uses do to execute the file as a script, and thus read the data structure (hash) into the program. Then JSON::PP module is used to make JSON out of it, since it should be installed on a system with Perl.

use warnings;
use strict;
use JSON::PP;

my %data = do './data.pm';

my $data_json = encode_json \%data;

print $data_json, "\n";  # just to see it

my $outfile = 'data.json';
open my $fh, '>', $outfile or die "Can't open $outfile: $!";
print $fh $data_json, "\n";
close $fh;

The whole job is done in the first two lines. The JSON::PP is a core module (since v5.14) but if an external dependency isn't a problem use JSON, which uses the fast JSON::XS if installed.

This nicely fits in a one-liner

perl -MJSON::PP -wE'say encode_json { do "./data.pm" }' > data.json

where the output is redirected to the file.

Both the program and the one-liner output (broken over lines for readability)

{"blah":{"other":"9","houses":"1","etc":
    [{"ppl":"3","etc":"5"},{"ppl":"5","etc":"9"}]}}

what is the content of the file data.json which is written.

For this to work the .pm file has to contain only a valid Perl data structure. If there is more variables than that one hash this won't work, since do doesn't return all that data. Then you'd have to process the file by other means.

Sign up to request clarification or add additional context in comments.

5 Comments

You need do './data.pm'. Without ./ it looks for data.pm in @INC, not the current directory.
@melpomene Oh ... thank you, corrected. (I had no idea that do would go to @INC) However, it worked exactly as posted for me (?). (It's just better anyway.)
If you use JSON::PP instead of JSON, your code won't have any external dependencies because JSON::PP has been a core module since 5.14.
It still mostly works because perl adds . to @INC by default (but that's about to go away in 5.26).
@melpomene Thank you for JSON::PP note, just the right thing here.
0

json.dumps converts from a Python object (like {"foo": True}) to a string representing that object as JSON (like '{"foo": true}'). You appear to be trying to go the other way and convert a file containing JSON to a Python object; the function that does this is json.load. However, that still won't work, as Devices.pm does not contain JSON. You'll need to either write a Perl script that imports Devices.pm and then dumps its contents as actual JSON or else write a parser for Perl in Python. I recommend the first approach.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.