Solved

Simple perl script

Posted on 2014-01-08
7
316 Views
Last Modified: 2014-01-27
Hi ,

As part of my learning , i like to know how to get the value splitted and format as below.

Input

Name:      Hendrickx Family
Email Address:      aaaaa@gmail.com
Country:      France
      
Nationality:      Belgian
Live In:      Big City
Number Of Children:      2

Output needed.

Name,Email Address,Country,Nationality,Live In,Number Of Children
Hendrickx Family,aaaaa@gmail.com,France,Belgian,Big City,2

Thanks,
Magento
0
Comment
Question by:magento
7 Comments
 
LVL 26

Assisted Solution

by:wilcoxon
wilcoxon earned 250 total points
ID: 39766567
Assuming one "row", this will work.  If there can be multiple entries, this will need some modification.
my (@hdr, @data);
while (<>) {
    chomp;
    my ($h, $d) = split /:\s+/;
    push @hdr, $h;
    push @data, $d;
}
print join(',', @hdr), "\n", join(',', @data), "\n";

Open in new window

0
 
LVL 84

Accepted Solution

by:
ozo earned 250 total points
ID: 39766579
perl -F':\s*' -lane '/:/and push(@x,shift @F),push @y,shift @F;END{$"=",";print "@x\n@y"}' << END_INPUT

Name:      Hendrickx Family
Email Address:      aaaaa@gmail.com
Country:      France
     
Nationality:      Belgian
Live In:      Big City
Number Of Children:      2
END_INPUT
0
 
LVL 5

Author Comment

by:magento
ID: 39776795
Hi ,

If its not too much trouble, can you teach me how to handle with multiple entries.?
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 40

Expert Comment

by:Sharath
ID: 39790141
Just added an IF condition to ignore blank lines in wilcoxon's solution.
my (@hdr, @data);
while (<>) {
    if (!/^$/) {
	chomp;
    my ($h, $d) = split /:\s+/;
    push @hdr, $h;
    push @data, $d;
	}
}
print join(',', @hdr), "\n", join(',', @data), "\n";

Open in new window

wilcoxon's solution gives this.
Name,Email Address,Country,,Nationality,Live In,Number Of Children
Hendrickx Family,aaaaa@gmail.com,France,,Belgian,Big City,2

Open in new window

with the if condition,
Name,Email Address,Country,Nationality,Live In,Number Of Children
Hendrickx Family,aaaaa@gmail.com,France,Belgian,Big City,2

Open in new window

0
 
LVL 84

Expert Comment

by:ozo
ID: 39790334
perl -F':\s*' -lane '(($x,$y)=@F)>1 and $y[$i+=defined $y[$i][$j=($x{$x}||=push@x,$x)-1]][$j]=$y;END{$"=",";print "@$_"for \@x,@y}'
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 39791541
Sharath's modification gets you part of the way there.  This should do what you want with multiple records.  It makes two assumptions:
1) Blank lines separate the records
2) All fields are present in each record

If either is untrue, it will need some more modification.
my (@hdr, @data, @row, $rec);
while (<>) {
    chomp;
    if (m{^\s*$}) {
        if (@row) {
            push @data, join(',', @row);
            @row = ();
            $rec++;
        }
    } else {
        my ($h, $d) = split /:\s+/;
        push @hdr, $h unless $rec;
        push @row, $d;
    }
}
push @data, join(',', @row) if @row;
print join(',', @hdr), "\n", join("\n", @data), "\n";

Open in new window

0
 
LVL 84

Expert Comment

by:ozo
ID: 39791553
http:#a39790334 assumes that any given named field appears at most once in each record, so that another appearance of the same field must be in a new record.
It also assumes that no field is named "0", but if that is a problem, and you have a recent version of perl, you can use //= instead of ||=
blank lines are ignored

http:#a39791541 seems to make the additional assumption that fields appear in the same order in each record, and its assumption 1) seems to be violated by the Input example in the original question.
0

Featured Post

Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Call Shell Script from Perl Script 6 134
Need some help with powershell script 5 55
REReplaceNoCase help 1 43
t-sql split string into multiple rows 7 119
I hope you'll find this tutorial useful and interesting. So let's try to extend Tcl with a new package.  For anyone more deeply interested please check out the book "Practical Programming in Tcl and Tk". It's really one of the best written books abo…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
The viewer will learn how to dynamically set the form action using jQuery.

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question