$str = "Data = [ {"name": "test","Address": "UK" "currency": "£" },{"name": "test2","Address": "US" "currency": "$" },{"name": "test","Address": "eur" "currency": "E" }
I want to display all address
its not multi line string . It all a single string
Please help on this
Thanks ,
TREE J
Your string is JSON! Treat it as such!
edit: I'm an idiot and can't tell when a question is tagged as perl instead of PHP :-) Link ammended.
This should work:
while ($str =~ /\"Address\":\S+\"(.*?)\"/g) {
print "Address = $1\n";
}
You do it by using the right tool for the job. In this case you fix the corrupt JSON with a regex and then use JSON to get the data:
#!/usr/bin/perl
use strict;
use warnings;
use JSON;
my $input = <DATA>;
my ($json) = $input =~ /DATA = (.*)/;
my $data = decode_json $json;
for my $record (#$data) {
print "$record->{name} has address $record->{Address}\n";
}
__DATA__
DATA = [ {"name": "test", "Address": "UK", "currency": "£" }, {"name": "test2", "Address": "US", "currency": "$" }, {"name": "test", "Address": "eur", "currency": "E" } ]
something like:
my $str = q(Data = [ {"name": "test","Address": "UK" "currency": "£" },{"name": "test2","Address": "US" "currency": "$" },{"name": "test","Address": "eur" "currency": "E" });
my #addresses = $str =~ /"Address":\s*"([^"]*)"/g;
print "#addresses\n";
HTH,
Paul
(PS: post real code, not pseudo code...)
Related
My Program is giving extra variable $t in output. Can anyone help me on this?
use XML::XML2JSON;
xml content
my $XML = '<file><sno>1</sno><process>VALID</process><validation_type>C</validation_type><file_type>HTML</file_type><line>2</line><column>78</column><status>0</status><type>Warning</type><code>001</code><rule>aligning content.</rule><desc>Check that non-breaking space.</desc></file>';
my $XML2JSON = XML::XML2JSON->new();
my $JSON = $XML2JSON->convert($XML);
print $JSON;
Output - Extra variable is coming $t
{
"#encoding": "UTF-8",
"#version": "1.0",
"file": {
"status": {
"$t": "0"
},
"rule": {
"$t": "aligning content."
},
"validation_type": {
"$t": "C"
},
"process": {
"$t": "VALID"
},
"sno": {
"$t": "1"
},
"file_type": {
"$t": "HTML"
},
"desc": {
"$t": "Check that non-breaking space."
},
"type": {
"$t": "Warning"
},
"code": {
"$t": "001"
},
"line": {
"$t": "2"
},
"column": {
"$t": "78"
}
}
}
Expected output is:
{
"sno": "1",
"process": "VALID",
"validation_type": "C",
"file_type": "HTML",
"line": "2",
"column": "78",
"status": "0",
"type": "Warning",
"code": "001",
"rule": "aligning content.",
"desc": "Check that non-breaking space."
}
The $t is content key as mentioned in the XML::XML2JSON documentation.
If your intention is to convert from XML to JSON, I would recommend to use XML::Simple and later you can encode using JSON.pm.
Code below:
#!/usr/bin/perl
use strict;
use warnings;
use JSON;
use XML::Simple;
#Create an object
my $xmlSimple = new XML::Simple;
my $XML = '<file><sno>1</sno><process>VALID</process><validation_type>C</validation_type><file_type>HTML</file_type><line>2</line><column>78</column><status>0</status><type>Warning</type><code>001</code><rule>aligning content.</rule><desc>Check that non-breaking space.</desc></file>';
#either we can pass a variable or a xml file which contains xml data
my $dataXML = $xmlSimple->XMLin($XML);
my $jsonString = encode_json($dataXML);
print $jsonString;
Output:
{
"process":"VALID",
"line":"2",
"column":"78",
"type":"Warning",
"file_type":"HTML",
"sno":"1",
"status":"0",
"rule":"aligning content.",
"code":"001",
"desc":"Check that non-breaking space.",
"validation_type":"C"
}
I have file:
"data_personnel": [
{
"id": "1",
"name": "Mathieu"
}
],
"struct_hospital": [
{
"id": "9",
"geo": "chamb",
"nb": ""
},
{
"id": "",
"geo": "jsj",
"nb": "SMITH"
},
{
"id": "10",
"geo": "",
"nb": "12"
},
{
"id": "2",
"geo": "marqui",
"nb": "20"
},
{
"id": "4",
"geo": "oliwo",
"nb": "1"
},
{
"id": "1",
"geo": "par",
"nb": "5"
}
]
How to use sed for for to have all the values of geo in struct_hospital? (chamb, jsj, , marqui, oliwo, etc ..)
The file can be in any form. With tabs, everything on a line, etc ..
As pointed out by Sundeep, it makes more sense to use a proper JSON parser.
But if you are looking for a one-time quick and dirty solution, then this might do:
sed -n '/^"struct_hospital"/,/^]/s/^.*"geo"\s*:\s*"\([^"]*\)"\s*,\?.*$/\1/p' input.txt
Sample output:
chamb
jsj
marqui
oliwo
par
Explanation:
/^"struct_hospital"/,/^]/ - only consider lines between struct_hospital and the closing bracket.
s/.../\1/p search and replace; only print the first capturing subpattern of every matching line
^.*"geo"\s*:\s*"\(.*\)"\s*,\?.*$ matches the geo lines; captures the value following the colon
In case the input spans a single line, you can use another sed invocation as a preprocessor to insert line breaks:
sed 's/]\|,/\n&/g'
This makes the full command:
sed 's/]\|,/\n&/g' input.txt | sed -n '/^"struct_hospital"/,/^]/s/^.*"geo"\s*:\s*"\([^"]*\)"\s*,\?.*$/\1/p'
{
"ticket": {
{
"id":"01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id":"07",
"language": "C++",
"edition": "second"
"author": "E.Balagurusamy"
}
}
,
"edition": "third",
"author": "Herbert Schildt"
}
That's my JSON file. I want to remove from file starting part {"ticket":
and ending part ,"edition": "third", "author": "Herbert Schildt" }.
Finally output I want like this:
{
"id":"01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id":"07",
"language": "C++",
"edition": "second"
"author": "E.Balagurusamy"
}
}
Note
Don't use regular expression, using only JSON Perl.
update
#!/usr/bin/perl
use JSON;
use Data::Dumper;
use Getopt::Long;
my($infile);
GetOptions('inFile=s' => \$infile);
my $json;
{
local $/;
open my $fh, "<", "$infile";
$json = <$fh>;
close $fh;
}
my $text = decode_json($json);
I have done this up to decode, but how to remove the starting and ending parts?
Assuming the syntax errors in your JSON file are by accident and fixing it with a comma and an array structure, this works:
#!/usr/bin/env perl
use strict;
use warnings;
use JSON;
my $json = do {
local $/;
<DATA>;
};
my $data = decode_json($json);
my $data2 = $data->{ticket};
my $json2 = encode_json($data2);
print $json2, "\n";
__DATA__
{
"ticket": [
{
"id":"01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id":"07",
"language": "C++",
"edition": "second",
"author": "E.Balagurusamy"
}
],
"edition": "third",
"author": "Herbert Schildt"
}
Prints out:
[{"language":"Java","edition":"third","author":"Herbert Schildt","id":"01"},{"language":"C++","edition":"second","author":"E.Balagurusamy","id":"07"}]
Suppose i have string result in json format as below.
{ "errorcode": 0, "message": "Done", "login": [ { "session_timeout": "1800", "token": "1370907977", "sessionid": "##F7A7E49F7FCFF35D3F821201CBF2F7CB5937E4AC99BF2AF74B508A1C8B3F", "username": "" } ] }
How can get a hash table from this like,
hash[errorcode] = 0;
hash[message] = Done;
PS: without using any additional modules and using simple string functions.
Use JSON module for parsing json structures to perl
use strict;
use warnings;
use JSON;
my $json_text = q({ "errorcode": 0, "message": "Done", "login": [ { "session_timeout": "1800", "token": "1370907977", "sessionid": "##F7A7E49F7FCFF35D3F821201CBF2F7CB5937E4AC99BF2AF74B508A1C8B3F", "username": "" } ] });
my $href = decode_json($json_text);
print $href->{errorcode}, $href->{message}, "\n";
I suppose that the non-module solution would be to cut and paste the relevant code from an existing module.
But that would be a terrible idea. Far better to just install the module.
In a file :
"name": "test","Address": "UK" "currency": "£" no:121212 ,
"name": "test1","Address": "UK" "currency": "£" no:12123212 ,
"name": "test2","Address": "UK" "currency": "£" no:121223212 ,
"name": "test3","Address": "UK" "currency": "£" no:121223212 ,
"name": "test4","Address": "UK" "currency": "£" no:121223212 ,
I want replace all the no into *
"name": "test","Address": "UK" "currency": "£" no:***** ,
"name": "test1","Address": "UK" "currency": "£" no:***** ,
"name": "test2","Address": "UK" "currency": "£" no:***** ,
"name": "test3","Address": "UK" "currency": "£" no:***** ,
"name": "test4","Address": "UK" "currency": "£" no:***** ,
and want append back into file
This one-liner should do it:
perl -i.bak -pe 's/(?<=no:)\d+/****/' filename
$ perl -pe 's/no:\d+/no:*****/' < input_file > output_file
cat input | perl -lne 's/^(.+)no:(\d+)(.*)/print"$1no:","*" x length($2),"$3"/e' > output
I might be tempted to use File::Map to change the file in place. If I do that, however, I have to replace the digits one-for-one since this won't move the other characters in the file:
use File::Map qw(map_file);
map_file my $map, 'test.txt', '+<';
$map =~ s/(?<=no:)(\d+)(?=\s*,$)/ '*' x length $1 /meg;