2015-06-09 6 views
0

Мне нужно отредактировать приведенный ниже конфигурационный файл с помощью Perl. Мне нужно проверить, соответствует ли cp 10000 и custcap - 99999, если это так.Редактировать json using Perl

Если cp не соответствует 10000, просто выйдите из файла без внесения изменений.

Насколько я понимаю, мы можем использовать Perl-файлы для открытия файла и модуль JSON для редактирования, но я не уверен в редактировании файла.

Может ли кто-нибудь помочь мне с редактированием файла?

{ 
    "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 
       } 
      } 
     ] 
     } 

Фрагмент кода:

#!/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; 

ответ

1

Проблема № 1: Вы просто прочитать первую строку файла.

Один трюк, чтобы прочитать весь файл сразу, - использовать local $/. С некоторой проверки ошибок и определения объема, который будет выглядеть следующим образом:

my $qfn = 'data.json'; 

my $json; 
{ 
    open(my $fh, "<", $qfn) 
     or die("Can't open file \"$qfn\": $!\n"); 
    local $/; 
    $json = <$fh>; 
} 

Задача № 2: Вам нужен некий цикл, так как вы должны проверить каждый из объектов в cus.

for my $cus (@{ $data->{global}{cus} }) { 
    $cus->{q}{custcap} = 99999 
     if $cus->{cp} == 10000; 
} 
+0

Спасибо за помощь ур – user3587025

+0

Но я только что заметил, что в конце печатается «versio n»: «15320029», которая была первой строкой файла. – user3587025

+0

Формат файла выглядит хорошо.но порядок параметров и фигурные скобки полностью перепутаны. – user3587025

1

@kjpires правильно, что опубликованный фрагмент не загружает весь файл и не будет его правильно разбирать.

Это только половина решения. Опубликованный фрагмент неправильно перемещает структуру JSON.

Корневой узел имеет global узел, который имеет cus узел, который является массивом, и каждый cus узла может иметь q узел, который имеет свойство custcap. Ваш фрагмент опускает cus массив и пытается получить доступ к q непосредственно

Ваши требования не специфичны относительно того, что делать, если custcap появляется несколько раз. Если предположить, что вам необходимо обновить каждое вхождение custcap, если его текущее значение 10000 с 99999, то вам необходимо заменить

$data->{'q'}->{'custcap'}->[1] = "9999";

с чем-то вроде этого:

for my $customer (@{$data->{global}{cus}}) { 
     $customer->{q}{custcap} = 99999 if ($customer->{cp} == 10000); 
} 
+0

Когда я компилирую код, я вижу следующую ошибку: или} ожидаемый при анализе объекта/хеша при смещении символов 1106 (до «\ n») – user3587025

+0

Я думаю, что это связано с вашим объектом JSON. Отсутствует закрытие} – EmFi

+0

#!/Usr/bin/perl use strict; использовать предупреждения; использовать JSON; my $ json; { open my $ fh, "<", "cfg.txt" или умереть ("Не удается открыть файл \" имя файла \ ": $! \ N"); местные $ /; $ json = <$fh>; } my $ data = decode_json ($ json); для моего $ кли (@ {$ данных -> {глобальный} {Кас}}) { $ Кас -> {д} {custcap} = 99999 если $ Кас -> {ф} == 10000; } #open файла и сохраните изменения { открывает $ Ф.Х., «>», «имя файла» или умереть («Невозможно открыть файл \» имя файла \ «: $ \ п»); местные $ /; $ json = <$fh>; } ~ ~ – user3587025

1

Одна проблема заключается в том, что my $json = <$fh>; Безразлично Не читайте весь файл: вы просто получаете одну строку файла (а затем разбираете только одну строку, которая, вероятно, должна завершиться неудачей, если она не находится в одной строке).

Одним из быстрых решений является определение окончательного терминатора конца строки с использованием: $/ = undef;, прежде чем вы начнете читать ваш файл. Другим решением является использование модуля File::Slurp.