Reputation: 183
I need to edit the below config file using Perl. I need to check if cp
is 10000 and set custcap
to 99999 if so.
If the cp
is not equal to 10000, just exit out of the file without making changes.
My understanding is we can use Perl file handles to open the file, and the JSON module for editing, but I'm not really sure about editing the file.
Can some one help me out with editing the file?
{
"version": "15320029",
"global": {
"ap": {
"log": "info",
"hyd": {
"log": "info",
"qo": false
}
},
"cus": [
{
**"cp": "10000"**,
"ser": "XYZ",
"usesr": false,
"services": {
"acc": {
"ips": {
"usesr": false
}
}
},
"q": {
"policy": "CAP",
**"custcap": 3000000**
}
},
{
"cp": "10441",
"ser": "abc",
"usesr": false,
"services": {
"acc": {
"ips": {
"usesr": false
}
}
},
"q": {
"policy": "CAP",
"custcap": 3000000
}
}
]
}
Code snippet :
#!/usr/bin/perl
use strict;
use warnings;
use JSON;
open my $fh, "<", "data.json";
my $json = <$fh>;
close $fh;
my $data = decode_json($json);
$data->{'q'}->{'custcap'}->[1] = "9999";
open my $fh, ">", "data.json";
print $fh encode_json($data);
close $fh;
Upvotes: 0
Views: 3118
Reputation: 385829
Problem #1: You just read the first line of the file.
One trick to read the whole file at once is to use local $/
. With some error checking and scoping, that will look like:
my $qfn = 'data.json';
my $json;
{
open(my $fh, "<", $qfn)
or die("Can't open file \"$qfn\": $!\n");
local $/;
$json = <$fh>;
}
Problem #2: You need some kind of loop since you need to check each of the objects in cus
.
for my $cus (@{ $data->{global}{cus} }) {
$cus->{q}{custcap} = 99999
if $cus->{cp} == 10000;
}
Upvotes: 1
Reputation: 23450
@kjpires is correct that the posted snippet does not load the entire file, and will not parses it correctly.
That's only half the solution. The posted snippet traverses the JSON structure incorrectly.
The root node has a global
node which has a cus
node that is an array, and each cus
node can have a q
node which has a custcap
property. Your snippet omits the cus
array and attempts to access q
directly
Your requirements aren't specific as to what to do if custcap
appears multiple times. Assuming that you need to update each occurrence of custcap
if its current value is 10000 with 99999 then you need to replace
$data->{'q'}->{'custcap'}->[1] = "9999";
with something like this:
for my $customer (@{$data->{global}{cus}}) {
$customer->{q}{custcap} = 99999 if ($customer->{cp} == 10000);
}
Upvotes: 1
Reputation: 740
One problem is that my $json = <$fh>;
doesn't read the whole file: you are just getting one line of the file (and then parsing just that one line which should probably fail unless it is all on one line).
One quick solution is to undefine the input end-of-line terminator using: $/ = undef;
before you read your file. Another solution is to use the File::Slurp module.
Upvotes: 1