Extracting sub string using Perl - perl

I have string as follows.
{
"id": "1304145"
,"Name" : "Ravi"
,"State" : "KAR"
,"Comp" : "CTL"
}
,{
"id": "2488398"
,"Name" : "Abhik"
,"State" : "TEL"
,"Comp" : "WFG"
}
,{
"id": "89039487"
,"Name" : "Jana"
,"State" : "ODS"
,"Comp" : "TOT"
}
I want to extract each of the sub-string present in a {} and make a format as follws
ID Name State Comp
1304145 Ravi KAR CTL
2488398 Abhik TEL WFG
89039487 Jana ODS TOT
I tried it, but my scripts are not giving the exact outputs.
Need your help in solving this.

Looks a lot like JSON.
If it is:
#!/usr/bin/env perl
use strict;
use warnings 'all';
use JSON;
my $json = from_json(do{local $/;<DATA>});
my #header = qw ( id Name State Comp );
print join ( "\t", #header ), "\n";
foreach my $row ( #$json ) {
print join ( "\t",#{$row}{#header} ),"\n";
}
__DATA__
[{
"id": "1304145"
,"Name" : "Ravi"
,"State" : "KAR"
,"Comp" : "CTL"
},
{
"id": "2488398"
,"Name" : "Abhik"
,"State" : "TEL"
,"Comp" : "WFG"
}
,{
"id": "89039487"
,"Name" : "Jana"
,"State" : "ODS"
,"Comp" : "TOT"
}
]
Gives:
id Name State Comp
1304145 Ravi KAR CTL
2488398 Abhik TEL WFG
89039487 Jana ODS TOT
That's assuming that you do have JSON though - I had to add [] around your snippet. If it isn't JSON then someone's done something dirty, in creating something that looks a lot like JSON, but that isn't.

If for some reason the data isn't supposed to be JSON, and the keys and values are always enclosed in double-quotes, then you can parse it easily with regular expressions
use strict;
use warnings 'all';
my $s = <<END_STRING;
{
"id": "1304145"
,"Name" : "Ravi"
,"State" : "KAR"
,"Comp" : "CTL"
}
,{
"id": "2488398"
,"Name" : "Abhik"
,"State" : "TEL"
,"Comp" : "WFG"
}
,{
"id": "89039487"
,"Name" : "Jana"
,"State" : "ODS"
,"Comp" : "TOT"
}
END_STRING
my #data = map { { /"([^"]*)"/g } } $s =~ /\{[^{}]*\}/g;
my $fmt = "%-11s %-7s %-7s %s\n";
printf $fmt, qw/ ID Name State Comp /;
for my $item ( #data ) {
printf $fmt, #{$item}{qw/ id Name State Comp /};
}
output
ID Name State Comp
1304145 Ravi KAR CTL
2488398 Abhik TEL WFG
89039487 Jana ODS TOT

Related

Powershell add column name to array data then convert it to JSON

Basically I formed an array of data based on certain conditions inside a loop and arrary data is something like this:
student1 RL123 S12 student2 RL423 S32 student6 RL166 S02 student34 RL993 P12 student99 RL923 S12
Above array data needs to be converted to JSON as below:
{
"Name" : "student1"
"RollNo" : "RL123"
"SubjectID" : "S12"
},
{
"Name" : "student2"
"RollNo" : "RL423"
"SubjectID" : "S32"
},
{
"Name" : "student6"
"RollNo" : "RL166"
"SubjectID" : "S02"
},
{
"Name" : "student34"
"RollNo" : "RL993"
"SubjectID" : "RL993"
},
{
"Name" : "student99"
"RollNo" : "RL923"
"SubjectID" : "S12"
}
If indeed your array is an array of strings (let's call it $students), you can skip the below line.
However, the way you have formatted it in your question makes it a string with space-separated items, so if that is the case, we should create a proper array from it by splitting on the whitespaces:
$students = 'student1 RL123 S12 student2 RL423 S32 student6 RL166 S02 student34 RL993 P12 student99 RL923 S12' -split '\s+'
Now just iterate over the values in the array and create objects using 3 array elements on each object:
$data = for ($i = 0; $i -lt $students.Count; $i+=3) {
[PsCustomObject]#{
Name = $students[$i]
RollNo = $students[$i + 1]
SubjectID = $students[$i + 2]
}
}
# here you convert the object array to JSON
$data | ConvertTo-Json
Output:
[
{
"Name": "student1",
"RollNo": "RL123",
"SubjectID": "S12"
},
{
"Name": "student2",
"RollNo": "RL423",
"SubjectID": "S32"
},
{
"Name": "student6",
"RollNo": "RL166",
"SubjectID": "S02"
},
{
"Name": "student34",
"RollNo": "RL993",
"SubjectID": "P12"
},
{
"Name": "student99",
"RollNo": "RL923",
"SubjectID": "S12"
}
]
the opening [ and closing ] denote that we're dealing with an array in Json syntax

Perl get array element from mongodb

I wanted to fetch array element and store in Perl variable. If I put 0 in replace of ? in $cur->{Type}[?]->{_id} I'm able to get only one array element but I want all. below is my collection
{
"_id" : ObjectId("5b7fdb050cc3c23478005741"),
"DBName" : "sample",
"DBServerURL" : "mongodb://localhost:27017/",
"Type" : [
{
"_id" : ObjectId("5b801dc963f8c81df83891bd")
},
{
"_id" : ObjectId("5b801dc963f8c81df83891be")
},
{
"_id" : ObjectId("5b801dc963f8c81df83891bf")
},
{
"_id" : ObjectId("5b801dc963f8c81df83891c0")
}
]
}
I'm trying to get ObjectId from all fields
$cursor = $CustColl->find(
{DBName => "sample",DBServerURL => "mongodb://localhost:27017/"},{'_id' => 1, 'Type.$._id' => 1, 'DBServerURL' => 1, 'DBName' => 1}
);
while(my $cur = $cursor->next){
my $cid = "$cur->{_id}" ;
my $jid = "$cur->{Type}[?]->{_id}" ;
my $url = "$cur->{DBServerURL}" ;
my $name = "$cur->{DBName}" ;
print "$cid : $jid : $url : $name\n" ;
}
I wanted an output like below:
5b7fdb050cc3c23478005741 : 5b801dc963f8c81df83891bd : mongodb://localhost:27017/ sample
5b7fdb050cc3c23478005741 : 5b801dc963f8c81df83891be : mongodb://localhost:27017/ sample
5b7fdb050cc3c23478005741 : 5b801dc963f8c81df83891bf : mongodb://localhost:27017/ sample
5b7fdb050cc3c23478005741 : 5b801dc963f8c81df83891c0 : mongodb://localhost:27017/ sample
You are almost there. First, I fixed up your data to make it JSON but that's not a big deal:
my $json = q([{
"_id" : "5b7fdb050cc3c23478005741",
"DBName" : "sample",
"DBServerURL" : "mongodb://localhost:27017/",
"Type" : [
{
"_id" : "5b801dc963f8c81df83891bd"
},
{
"_id" : "5b801dc963f8c81df83891be"
},
{
"_id" : "5b801dc963f8c81df83891bf"
},
{
"_id" : "5b801dc963f8c81df83891c0"
}
]
} ]);
use JSON::XS;
my $perl = decode_json( $json );
That's a JSON array so you can go through it one element at a time. In Perl that shows up as an array reference Using the postfix dereference introduced in v5.20 makes this palatable (but not so hard without it):
while(my $cur = shift $perl->#*){ # or #$perl
my $cid = $cur->{_id} ;
my $url = $cur->{DBServerURL} ;
my $name = $cur->{DBName} ;
foreach my $hash ( $cur->{Type}->#* ) { # or #{ $cur->{Type} }
my $jid = $hash->{_id};
print "$cid : $jid : $url : $name\n" ;
}
}
The trick is that the $jid stuff is in another array and you want to go through those individually. There's a foreach inside the while to do that. It runs once for each of those and outputs the lines.

Perl Newbie - Printing value from array

I am brand new to perl. I am trying to grab a string out of some JSON output. My code below works, but seems like there is a smarter way to do this. Here is a sample of the JSON
$VAR1 = '{
"hasDetailRows" : true,
"reportMetadata" : {
"reportFormat" : "TABULAR",
"detailColumns" : [ "SUBJECT", "COMMENT_CREATED_DATE", "CASE_COMMENT_CREATED_BY" ],
"reportBooleanFilter" : null,
"reportFilters" : [ {
"column" : "CASE_COMMENT_CREATED_BY",
"operator" : "equals",
"value" : "Username"
} ],
"aggregates" : [ "RowCount" ],
"groupingsDown" : [ ],
"groupingsAcross" : [ ],
"developerName" : "My_Comments",
"reportType" : {
"type" : "CaseList",
"label" : "Cases"
},
"name" : "My Comments",
"id" : "REDCATED",
"currency" : null
},
"factMap" : {
"T!T" : {
"rows" : [ {
"dataCells" : [ {
"value" : "ID",
"label" : "Description"
}, {
"value" : "2014-02-17T22:01:17Z",
"label" : "2/17/2014 4:01 PM"
}, {
"value" : "USER ID",
"label" : "User Name"
} ]
}`
What I need is that label with the timestamp.
And here is my code
#!/usr/bin/perl
use warnings;
use strict;
use WWW::Mechanize;
use WWW::Salesforce;
use Data::Dumper;
use JSON -support_by_pp;
use 5.010;
use Date::Parse;
my $mech = WWW::Mechanize->new();
$mech->agent('Mozilla/5.0');
# Authenticate first via SOAP interface to get a session ID:
my $sforce = eval { WWW::Salesforce->login(
username => 'REDACTED',
password => 'REDACTED' ); };
die "Could not login to SFDC: $#" if $#;
# Get the session ID:
my $hdr = $sforce->get_session_header();
my $sid = ${$hdr->{_value}->[0]}->{_value}->[0];
#Our request
$mech->add_header( "Authorization" => "OAuth $sid" );
$mech->add_header( "X-PrettyPrint" => '1' );
$mech->get("SOME URL THAT RETURNS JSON");
my $content = $mech->content;
my $json = new JSON;
my $json_text = $json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($content);
Here is what I have currently that grabs the value that I want from $content. All I need is the first result which is why I am killing the loop after the first run. Everytime I have tried this without a loop I get "Not a HASH reference". So all I need to know is the correct syntax for printing out the value of $timestamp.
foreach my $field(#{$json_text->{factMap}->{'T!T'}->{rows}}){
my $now = time();
my $timestamp = str2time($field->{dataCells}[1]->{'label'});
my $diff = int (($now - $timestamp)/60);
my $current = getLoggingTime();
print $current . " \t";
say "Time since last activity: " . $diff . " minutes!" ;
last;
}
sub getLoggingTime {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
my $nice_timestamp = sprintf ( "%04d-%02d-%02d %02d:%02d:%02d",
$year+1900,$mon+1,$mday,$hour,$min,$sec);
return $nice_timestamp;
}
I don't know what your without-a-loop version looks like, but this should work:
my $timestamp = str2time(
$json_text->{factMap}{'T!T'}{rows}[0]{dataCells}[1]{label}
);
Currently, you're looping over the elements of the array referenced by
$json_text->{factMap}{'T!T'}{rows}
...and stopping at the first entry
$json_text->{factMap}{'T!T'}{rows}[0]
...and dereferencing that to get to
$json_text->{factMap}{'T!T'}{rows}[0]{dataCells}[1]{label}

trying to automate Rally user creation using perl and json

We are tring to automate user creation using perl and json. I have this error on the PUT command:
<h1>Method Not Allowed</h1>
<p>The requested method PUT is not allowed for the URL /https://sandbox.rallydev.com/slm/webservice/1.43/user/create.js.</p>
</body></html>
',
'_rc' => '405',
Attempting POST gives me this:
<h1>Not Found</h1>
<p>The requested URL /https://sandbox.rallydev.com/slm/webservice/1.43/user/create.js was not found on this server.</p>
</body></html>
',
'_rc' => '404',
Is there an example of creating a Rally user with perl?
Here is a basic example in Perl showing how to create a Rally user. Requires the following Perl modules:
REST::Client
JSON
MIME::Base64
I tested this using v5.14.2 on Ubuntu 12.04.
use strict;
use warnings;
# Needed includes
use REST::Client;
use JSON;
use MIME::Base64;
use URI;
use URI::Split;
# User parameters
# Must be a Rally Subscription Administrator, or a Workspace Administrator
# in a Rally Workspace whose Workspace Admins have been granted user administration
# privileges
my $username='user#company.com';
my $password='topsecret';
# Rally connection parameters
my $base_url="https://rally1.rallydev.com";
my $wsapi_version = "1.43";
# Connect to Rally and create user
# ====================================
my $headers = {
Accept => 'application/json',
Authorization => 'Basic ' . encode_base64($username . ':' . $password)
};
# instantiate REST Client
my $rest_client = REST::Client->new();
# set host
$rest_client->setHost($base_url);
# Formulate POST request to create user
# Note that the a Rally User must have at least one Workspace Permission / Project Permission
# pair. Thus the user will be given User Permissions in the Default Workspace of the
# Subscription or Workspace Administrator whose RallyID is used to run this script.
# The user will receive Viewer-level permissions to the alphabetically
# First project in the Default Workspace of the Rally UserID used to run the script
my $new_rally_user_id = 'user12#company.com';
print "Connecting to Rally and attempting to create user of UserID: \n";
print $new_rally_user_id . "\n\n";
my $wsapi_endpoint = "/slm/webservice/" . $wsapi_version . "/";
my $user_create_endpoint = $wsapi_endpoint . "user/create.js";
my $user_post_body = '{"User": {"UserName": "' . $new_rally_user_id . '", "EmailAddress": "' . $new_rally_user_id . '"}}';
print "POST Body for user creation:\n";
print $user_post_body . "\n\n";
# Attempt Create
$rest_client->POST($user_create_endpoint, $user_post_body, $headers);
# Output JSON Response
print "Create Response:\n\n";
print $rest_client->responseContent();
Here's the outcome of running the script:
$ perl rally_create_user.pl
Connecting to Rally and attempting to create user of UserID:
user12#company.com
POST Body for user creation:
{"User": {"UserName": "user12#company.com", "EmailAddress": "user12#company.com"}}
Create Response:
{ "CreateResult" : { "Errors" : [ ],
"Object" : { "Boolean" : null,
"CUF" : null,
"CostCenter" : "None",
"CreationDate" : "2013-07-11T22:49:00.056Z",
"Date" : null,
"Department" : "None",
"Disabled" : false,
"DisplayName" : null,
"Editable" : null,
"EmailAddress" : "user12#company.com",
"FirstName" : null,
"LandingPage" : "/dashboard",
"LastLoginDate" : null,
"LastName" : null,
"LastPasswordUpdateDate" : "2013-07-11T22:49:00.056Z",
"MiddleName" : null,
"NetworkID" : null,
"ObjectID" : 12345678913,
"OfficeLocation" : "None",
"OnpremLdapUsername" : null,
"Phone" : null,
"RevisionHistory" : { "_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/revisionhistory/12345678915.js",
"_type" : "RevisionHistory"
},
"Role" : "None",
"ShortDisplayName" : null,
"Specialty" : null,
"String" : null,
"Subscription" : { "_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/subscription/12345678914.js",
"_refObjectName" : "My Subscription",
"_type" : "Subscription"
},
"SubscriptionAdmin" : false,
"TeamMemberships" : [ ],
"Text" : null,
"UserName" : "user12#company.com",
"UserPermissions" : [ { "_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/workspacepermission/12345678917u12345678918w3.js",
"_refObjectName" : "My Workspace User",
"_type" : "WorkspacePermission"
},
{ "_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/projectpermission/12345678919u12345678920p1.js",
"_refObjectName" : "A Project",
"_type" : "ProjectPermission"
}
],
"UserProfile" : { "_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/userprofile/12345678921.js",
"_type" : "UserProfile"
},
"_CreatedAt" : "just now",
"_objectVersion" : "2",
"_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43",
"_ref" : "https://rally1.rallydev.com/slm/webservice/1.43/user/12345678922.js",
"_refObjectName" : "user12",
"_type" : "User",
"yesno" : null
},
"Warnings" : [ "API status is Deprecated and will become Not Supported on 2014-Jun-20" ],
"_rallyAPIMajor" : "1",
"_rallyAPIMinor" : "43"
You start your URI and its https scheme mistakenly with a /. Remove it.

Perl and MongoDB: Inserting Array of Objects into Key-Value Pairs

I'd like to insert into my MongoDB using perl the following BSON structure:
{"name" : "BOB", "stuff" : [{"area1": [1,2,3,4,5]}, {"area2": [5,6,7,8,9]}]}
But have had a hard time finding a good example of this. I tried the following:
#!/usr/bin/perl
use MongoDB;
use MongoDB::Database;
use MongoDB::OID;
my $conn = MongoDB::Connection->new;
my $db = $conn->test;
my $users = $db->real_time10;
$users->insert
({
"name" => "BOB",
"stuff" =>
"area1" => [1,2,3,4,5],
"area2" => [5,6,7,8,9]
});
Which grossly outputs upon query in the mongo shell:
db.real_time10.find()
{ "_id" : ObjectId("4fc912fa000207ec08000000"), "ARRAY(0xa5bdd4)" : "area2", "A
RAY(0x2f2e844)" : null, "name" : "BOB", "stuff" : "area1" }
What is going on? Is there a simple way to do this?
My dream/desired output would be:
> db.real_time10.find()
{ "_id" : ObjectId("4fc912fa000207ec08000000"), "stuff" : {"area1" : [1,2,3,4,5],
"area2": [5,6,7,8,9]}, "name" : "BOB" }
Your missing your anonymous-array-constructor (square-brackets) in your example code - but including them in your BSON example. To get your desired output try:
$users->insert({
"name" => "BOB",
"stuff" => {
"area1" => [1,2,3,4,5],
"area2" => [5,6,7,8,9]
}
});
By excluding the array constructor it builds up a hash with the supplied array key, value pairs so it would be parsed as the following (which matches your data-dump):
{
"name" => "BOB",
"stuff" => "area1",
[1,2,3,4,5] => "area2",
[5,6,7,8,9] => undef
}
Note: an array-ref in scalar context will be seen as a string like "ARRAY(0x6052b8)"
Ah, it's this:
#!/usr/bin/perl
use MongoDB;
use MongoDB::Database;
use MongoDB::OID;
my $conn = MongoDB::Connection->new;
my $db = $conn->test;
my $users = $db->real_time10;
$users->insert({
"name" => "BOB",
"stuff" =>
{"area1" => [1,2,3,4,5],
"area2" => [5,6,7,8,9]}
});
This outputs:
{ "_id" : ObjectId("4fc91f110064e9d40b000000"), "name" : "BOB", "stuff" : { "are
a2" : [ 5, 6, 7, 8, 9 ], "area1" : [ 1, 2, 3, 4, 5 ] } }