Re: Combining multiple lines based on the given condition
by Eily (Monsignor) on Oct 18, 2013 at 19:20 UTC
|
The first 13 lines of Text::CSV already show you how to do half the work (there is one extra line though). Except instead of pushing into an array, you have to push the row inside a hash of arrays with the first column has the key.
push @{ $yourHash{shift @$row} }, @$row # shift returns the first element of an array and deletes it from it
If you don't know how to uses hashes and hashes of arrays, read perldsc
Edit: ahem ... square brackets for a hash ... this wouldn't have worked well.
| [reply] [d/l] |
|
|
Could you please help me bit more. Because I'm new to perl.
Thanks.
| [reply] |
Re: Combining multiple lines based on the given condition
by 2teez (Vicar) on Oct 18, 2013 at 19:31 UTC
|
Hi anony,
Welcome to the Monastery.
Could anyone help me to write a command which displays as follows..
How would you solve this yourself? Please check the following: How do I post a question effectively?. Ofcourse we are ready to help, but you must show some effort on your part.
If you tell me, I'll forget.
If you show me, I'll remember.
if you involve me, I'll understand.
--- Author unknown to me
| [reply] |
Re: Combining multiple lines based on the given condition
by Laurent_R (Canon) on Oct 18, 2013 at 21:39 UTC
|
It would also be good that you use code tags (<c> and </c>) to show the content of your file as it is really formated (as well as the desired output), since the solution might be different if your file looks like this:
abc,2,3,4,5,6 abc,7,5,2,1,6,2,3 abc,8,2,1,3,1,4 ....... def,8,9,4,5,6 def,5,6,2,1
or if it looks like that:
abc,2,3,4,5,6
abc,7,5,2,1,6,2,3
abc,8,2,1,3,1,4
.......
def,8,9,4,5,6
def,5,6,2,1
The fact that you don't have commas before the three-letter groups leads me to think that it is more probably the second case, but we can't know for sure.
| [reply] [d/l] [select] |
|
|
Thanks all of you for your replies. Please find the following code.If you have any further changes to this code please let me know .Also, I don't know how to use text::csv , so if anyone could help, it will be nice.
#!usr/bin/perl
use strict;
open FH, "/home/test1/hello.csv" or die;
my @array,@array1;
#----------I'm pushing all abc's and def's data into respective arrays
+---------------------------
while(<FH>)
{
if ($_=~/^abc/)
{
push(@array,$_);
}
elsif($_=~/^def/)
{
push(@array1,$_);
}
}
#----------I'm writing only one for loop for abc, it will be same for
+def too. ------------------------------
my @hello;
foreach my $i(0..$#array-1)
{
#-------below code: it splits the second abc and and so on. i.e., stri
+ps second abc from the digits.-------------------
@hello=split /^\w+\,/,$array[$i+1];
foreach my $j(0..$#hello)
{
#--------below code:this is for replacing \n of first abc,2,3,4,5,6 wi
+th a comma ( ex: abc,2,3,4,5,6, )
$array[$i]=~s/\n/,/g;
#--------------below code:here it concatenates the data ( data should
+look like: 2,3,4,5,6,7,5,2,1,6,2,3,8,2,1,3,1,4 )----------
abc,$array[$i]=$array[$i].$hello[$j];
print $array[$i],"\n";
}
}
# In my above code, the data is concatenated as follows:
abc,2,3,4,5,6
,7,5,2,1,6,2,3
,8,2,1,3,1,4
#But expected output is :
abc,2,3,4,5,6,7,5,2,1,6,2,3,8,2,1,3,1,4
| [reply] [d/l] |
|
|
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV>mergetest1.pl
Global symbol "@array1" requires explicit package name at
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV\mergetest1.p
+l line 5.
Global symbol "@array1" requires explicit package name at
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV\mergetest1.p
+l line 18.
Bareword "abc" not allowed while "strict subs" in use at
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV\mergetest1.p
+l line 41.
Execution of C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV\mer
+getest1.pl
aborted due to compilation errors.
If you don't know how to resolve the errors listed above, ask about those. I would be glad to help you learn this stuff on any level. But I emphasize I will help. This means you have to be there, too. :-)
Also, please post your input file (also using a copy and paste function, please), and put it in between
<readmore>
<code>
{your data here}
</code>
</readmore>
tags for easy downloading.
As noted by Laurent_R, what you posted gives us an idea of what your input data looks like, but it's not quite specific enough given that you ask to help format it exactly like the output you want. Can't get the exact output without the exact input. :-)
Finally, once we have your core code working, we will examine the possibility of using the Text::CSVmodule or something similar, and we can cover how you make that happen at that time.
Let's crawl first, then walk, then run, then, perhaps, even fly. :-)
| [reply] [d/l] [select] |
|
|
use warnings;
use strict;
my $l = 'abc,2,3,4,5,6 abc,7,5,2,1,6,2,3 abc,8,2,1,3,1,4 ....... def,8
+,9,4,5,6 def,5,6,2,1 ';
my %hash;
my $k;
for (split/[,. ]+/ => $l){
if(/\D+?/){
$k = $_
}else{
push @{$hash{$k}},$_
}
}
print $_,',',join (',' => @{$hash{$_}}),$/ for sort keys %hash;
Secondly, since your input is a CSV file, it is better you use module like Text::CSV or Text::CSV_XS. See an example below with a modified OP dataset.
#!/usr/bin/perl
use warnings;
use strict;
use Text::CSV;
use Data::Dumper;
my %hash;
my $csv = Text::CSV->new( { binary => 1 } )
or die "can't use CSV" . Text::CSV->error_diag();
while ( my $row = $csv->getline(*DATA) ) {
push @{ $hash{ shift @$row } }, @$row; # as previously mentioned
+ by Eily
}
$csv->eof or $csv->error_diag();
print Dumper \%hash;
__DATA__
abc,2,3,4,5,6
abc,7,5,2,1,6,2,3
abc,8,2,1,3,1,4
def,8,9,4,5,6
def,5,6,2,1
If you tell me, I'll forget.
If you show me, I'll remember.
if you involve me, I'll understand.
--- Author unknown to me
| [reply] [d/l] [select] |
|
|
# In my above code, the data is concatenated as follows:
abc,2,3,4,5,6
,7,5,2,1,6,2,3
,8,2,1,3,1,4
#But expected output is :
abc,2,3,4,5,6,7,5,2,1,6,2,3,8,2,1,3,1,4
Again, we need to see the input file correctly formatted before we can say for sure what you need to do, but it seems very very likely that your problem comes from the fact that the input is split into separate lines, each of which having a trailing end-of-line character. In this case, you simply need to remove that character from your input lines immediately after you read it (although it could be done later, it is best to do it right away). Change your code as follows:
while(<FH>)
chomp;
{
# ...
There are many other things to be said about your code, but this correction should at least solve your immediate problem. I'll wait for a correctly formatted input before making any further comments.
| [reply] [d/l] [select] |
Re: Combining multiple lines based on the given condition
by marinersk (Priest) on Oct 18, 2013 at 20:32 UTC
|
Hello anony,
Could anyone help me to write a command which displays as follows:
Sure. Show us the code you're using to read the file. Then we can help you with the command needed to merge the data.
| [reply] |
Re: Combining multiple lines based on the given condition
by marinersk (Priest) on Oct 20, 2013 at 04:29 UTC
|
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV>type hello.csv
abc,2,3,4,5,6
abc,7,5,2,1,6,2,3
abc,8,2,1,3,1,4
def,8,9,4,5,6
def,5,6,2,1
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV>perl mergetest99
+.pl hello.csv
C:\Steve\Dev\PerlMonks\P-2013-10-18@1712-DataMergeCSV>type hello.csv.o
+ut.csv
abc,2,3,4,5,6,7,5,2,1,6,2,3,8,2,1,3,1,4
def,8,9,4,5,6,5,6,2,1
If this is what you are looking for and if you want to see how I did this, let's get your code working and I'd be glad to get you moving on this again.
On the other hand, if this is not what you are looking for, I suppose this demonstrates why you need to post the input file. :-) | [reply] [d/l] [select] |