vanuatu10 has asked for the wisdom of the Perl Monks concerning the following question:
Here is a very important question. If I have a file with variable length records, how can i make the records that same size?
Ent, Name,
SC011, BUN,
Tester,
Value,
#1008
Ent, Name,
FS0022L, FUN,
TL0324, PLEASE,
Tester,
Value,
#1002
Ent, Name,
SC004, TAKE,
K530, RUN,
Tester,
Value,
#1001
If the data between "Ent" and "Tester" are different as far as having one or two entries, how can I make the entries equal two and so on by adding new lines followed by commas. Each record in the file may have more than one entry between "Ent" and "Tester." If one record in the file has one entry between "Ent" and "Tester", and the others have eight, two, three,..... How would I alter each record with new lines to have the same number of lines. In the above case, the highest number would be two; but this could be higher in the file I have.
Example of output:
Ent, Name,
SC011, BUN,
,
Tester,
Value,
#1008
Ent, Name,
FS0022L, FUN,
,
TL0324, PLEASE,
Tester,
Value,
#1002
Ent, Name,
SC004, TAKE,
K530, RUN,
Tester,
Value,
#1001
Please help!
Edit by tye
Re: Equal line spacing in records of a file
by vladb (Vicar) on May 22, 2002 at 15:13 UTC
|
Considering I got your input data right, give a try to this script:
#!/usr/local/bin/perl
use strict;
use Data::Dumper; # use this module for debugging only!
my @recs = ([]);
my ($in_rec, $row_count, $max_rows) = 3x(0);
while (<DATA>) {
chomp;
if (/Ent/.../Tester/) {
# Inside a record!
# add record line...
push @{$recs[$#recs]}, $_;
$row_count++;
} else {
# add empty record (which will store lines
# for any new record to come).
push @recs, [];
$max_rows = $row_count if ($row_count > $max_rows);
$row_count = 0;
}
}
# uncomment these lines to debug..
# print Dumper(\@recs);
# print "max rows: $max_rows\n";
# cycle through array of records..
for (@recs) {
# if record is not empty..
if ($row_count = scalar @$_) {
my $i = 0;
# print all lines in this record
while ($i < $row_count - 1) {
print $$_[$i++] ."\n";
}
# print extra 'empty' lines to increase record
# size to that of the maximum record in the file.
print ",\n" while ($row_count++ < $max_rows);
# finally, print the closing line ('Tester,')
print $$_[$i] ."\n";
}
}
__DATA__
Ent,
Name,
SC011,
BUN,
Tester,
Value,
#1008
Ent,
Name,
FS0022L,
FUN,
TL0324,
PLEASE,
Tester,
Value,
#1002
Ent,
Name,
SC004,
TAKE,
K530,
RUN,
Tester,
Value,
#1001
And the output:
Ent,
Name,
SC011,
BUN,
,
,
Tester,
Ent,
Name,
FS0022L,
FUN,
TL0324,
PLEASE,
Tester,
Ent,
Name,
SC004,
TAKE,
K530,
RUN,
Tester,
UPDATE: Included a few comments inside the script to explain how it works. I also assume that each 'record' line is on a separate line. At least, that's how I understood the problem before the original post was reformatted properly ;).
_____________________
$"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+)
+-.*)$/;$_=["ps -e -o pid | "," $2 | "," -v "," "]`@$_`?{print"
++ $1"}:{print"- $1"}&&`rm $1`;print"\n";}
| [reply] [d/l] [select] |
Re: Equal line spacing in records of a file
by jmcnamara (Monsignor) on May 22, 2002 at 15:25 UTC
|
In the absence of further information I had to make some assumptions:
1. That each record was delimited by #\d+, eg #1008
2. That the delimiter was preceded by Value and Tester
So that following might not be quite what you need but it will give you a start.
#!/usr/bin/perl -w
use strict;
my $rec_index;
my @rec_refs;
my @record;
my $max = 0;
my $count = 0;
while (<DATA>) {
$count++;
push @record, $_;
if (/#\d+/) { # Match the end of record
push @rec_refs, [@record]; # Store the current record
@record = ();
$max = $count if $count > $max; # Track max fields in a rec
+ord
$count = 0;
}
}
# Iterate through the stored records and add the extra fields
foreach my $aref (@rec_refs) {
$count = 0;
foreach my $line (@$aref) {
# Add extra fields before the "Tester" field
print ",\n" x ($max - $count -3) if $line eq "Tester,\n";
print $line;
$count++;
}
}
__DATA__
Ent, Name,
SC011, BUN,
Tester,
Value,
#1008
Ent, Name,
FS0022L, FUN,
TL0324, PLEASE,
Tester,
Value,
#1002
Ent, Name,
SC004, TAKE,
K530, RUN,
K530, RUN,
Tester,
Value,
#1001
--
John.
| [reply] [d/l] |
|
Is there a way to give equal field spacing of thirty characters in each field of data in front of the comma?
For example: (30 - field data) = additonal spacing
Needed Output:
Ent , Name ,
SCO11 , RUN ,
Current Data:
Ent, Name,
SCO11, RUN,
Ent, Name,
NA932, TAKE,
I wrote the following code for equal spacing:
$counter = 0;
foreach(@newstuff){
$counter++;
if(m/Ent/){
$counter=0;}
if(m/Payor/){
if($counter > $hold){
$hold = $counter; }
}
}
$counter2 = 0;
foreach(@newstuff){
$counter2++;
if(m/Ent/){
$counter2=0;}
if(m/Payor/){
if($counter2 < $hold){
$temp = $counter2;
for($temp;$temp < $hold; $temp++){
#for($j=0;$j < $hold; $j++){
s/Payor/\nPayor/;
}
}
}
}
How can I make the file have equal field spacing?
There has be be a was to count the contents of each line in the array and add, assuming staticval = 30, spaces before the commas of each field minus the charater in each field.
In example, "Ent," would turn out to be staticval minus the number of characters found in Ent. This would be Ent followed by twenty-seven spaces and a comma.
Edit kudra,
2002-05-25
Added code tags
| [reply] [d/l] |
|
| [reply] |
|
- please use <code>..</code> tags when blanks are significant.
- sure there's a way: printf("%-30s,", $field);
cheers,
Aldo
__END__
$_=q,just perl,,s, , another ,,s,$, hacker,,print;
| [reply] [d/l] |
|
print pack('A30', $thing_that_should_be_30_chars_long);
# or
print pack('A30' x scalar(@stuff_to_pad), @stuff_to_pad);
| [reply] [d/l] |
Re: Equal line spacing in records of a file
by Mask (Pilgrim) on May 22, 2002 at 14:52 UTC
|
I do not understand this question at all.
What do you mean by saying record, is it a line from file? And what is entrie? Is it a string between commas? If yes - then you just shoul add some comas before output. | [reply] |
|
|