CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Moving around lines in a file

 



iphone
User

Aug 18, 2010, 1:54 PM

Post #1 of 23 (2257 views)
Moving around lines in a file Can't Post


Code
use strict;   
use warnings;
open my $file1, '<', 'features.txt' or die 'Cannot open file2';

while( <$file1> ){
if($_ =~ /CR/)/*if a line matches CR*/
{

Need help here
-----------loop-----------
file1++ until a line matches the word "CR" again,if it matches the word "CR"comeout of the loop with the current line as line number
print $_ if the line contains the word "data" or "case" in it
--------------------
}
}
close $file1;

Basically in between twolines that has the word "CR" I want to print all the lines that has the words data and case.Please guide me


BillKSmith
Veteran

Aug 18, 2010, 2:48 PM

Post #2 of 23 (2247 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post


Code
use strict;  
use warnings;
while (<DATA>){
next if !(/CR/ ... /CR/);
print if /(DATA|CASE)/;
}
__END__
MY DATA # Do not print
Return (CR) # Enable printing
More DATA # Print
any text # Do not print
In any CASE # Print
another CR # Disable printing
another CASE # Do not print



or even shorter:

Code
perl -n -e"print if /CR/ ... /CR/ and /DATA|CASE/;"

Good Luck,
Bill

(This post was edited by BillKSmith on Aug 18, 2010, 3:25 PM)


iphone
User

Aug 18, 2010, 4:05 PM

Post #3 of 23 (2241 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

Thanks for the reply Bill ,but my output should be like the following


Code
MY DATA      # Do not print  --->Print,if a line contains Data or Case,it has to printed  
Return (CR) # Enable printing
More DATA # Print
any text # Do not print
In any CASE # Print
another CR # Disable printing ---> Print if the following lines has a Data or Case
another CASE # Do not print ---> print ,if the line has a data or Case it has to be printed irrespective


The only problem is with the line containing CR,the line containing CR has to be printed only if the following lines has a "data" or "case" word in it before it encounters another line with a word "CR" in it.


(This post was edited by iphone on Aug 18, 2010, 4:17 PM)


Zhris
User

Aug 18, 2010, 5:56 PM

Post #4 of 23 (2219 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

Hi,

Personally I am unable to fully understand exactly what output you desire. If you are still having problems, could you provide example input, with your desired output. Its easier than simply trying to explain.

Chris


BillKSmith
Veteran

Aug 18, 2010, 6:20 PM

Post #5 of 23 (2215 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

I agree with Chris. I am not sure I understand your requirement, but here is my best guess.


Code
use strict; 
use warnings;
my $cr_line = '';
while (<DATA>){
if (/CR/){
$cr_line = $_;
}
elsif (/DATA|CASE/){
print $cr_line, $_;
$cr_line = '';
}
}
__END__
MY DATA # Print,if a line contains Data or Case,it has to printed
Return (CR) # Print ("DATA" in followin block)
More DATA # Print
any text # Do not print
In any CASE # Print
another CR # Do not print
something # Do not print
this CR # Print ("CASE" in following block)
stuff # Do not print
just in CASE # Print

Good Luck,
Bill


iphone
User

Aug 19, 2010, 12:33 PM

Post #6 of 23 (2188 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

Sorry about not being clear,I manipulated the below code and adjusted to my requirement.

I have one last question.

print $cr_line, $_; -->Instead of printing,can you please help in putting this data in an excel sheet?

Found this on google,trying this manipulate this with difficulty

Code
use Win32::OLE; 
$file = "C:\\temp\\MyTest.xls";
$excel = Win32::OLE->GetActiveObject('Excel.Application');
unless($excel)
{
$excel = new Win32::OLE('Excel.Application', \&QuitApp)
or die "Could not create Excel Application object";
}

$excel->{Visible} = 1;
$excel->{SheetsInNewWorkBook} = 1;
$workbook = $excel->Workbooks->Add();
$worksheet = $workbook->Worksheets(1);
$worksheet->{Name} = "Directory listing";

@files = glob('*');

$range=$worksheet->Range('A1:C1');
$range->{Value} = ['Filename', 'Size', 'Time'];

my $cellrow = 2;

foreach $file (@files)
{
my ($size,$mtime) = (stat($file))[7,9];
$range=$worksheet->Range(sprintf("%s%d:%s%d",'A',$cellrow,'C',$cellrow));
$range->{Value} = [$file,$size,scalar localtime $mtime];
$cellrow++;
}
$workbook->SaveAs($file);

sub QuitApp
{
my ($object) = @_;
$object->Quit();
}



BillKSmith
Veteran

Aug 19, 2010, 8:31 PM

Post #7 of 23 (2165 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

Perhaps my elsif clasue would be clearer as:


Code
    elsif (/DATA|CASE/){ 
if ($cr_line) {
print $cr_line;
$cr_line = '';
}
print $_;
}



To put in spread sheet, replace each print with range and value. You have to decide how the spread sheet should look.
Good Luck,
Bill


iphone
User

Aug 19, 2010, 8:55 PM

Post #8 of 23 (2159 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

How do i change the below code so that I can write data to more rows and columns as long as the line matches data or case?Currently i am just writing to row1/col1 and row2/col1


Code
    #!/usr/bin/perl -w 

use strict;
use Spreadsheet::WriteExcel;

# Row and column are zero indexed
my $row1 = my $col1 = 0;
my $row2 = 1;

# Create a new Excel workbook
my $workbook = Spreadsheet::WriteExcel->new("perl.xls");
my $worksheet = $workbook->addworksheet();

my $cr_line = '';
open my $line, '<', 'features.txt' or die 'Cannot open file2';

while( <$line> ){

if (/CR/){
$cr_line = $_;
}
elsif (/Data|case/i){
#print $cr_line, $_;
#########how to write the lines that matches data|case after row2#########
$worksheet->write($row1, $col1, $cr_line);
$worksheet->write($row2, $col1, $_);
$cr_line = '';
}
}

$workbook->close();

Code



      
    


Zhris
User

Aug 19, 2010, 9:16 PM

Post #9 of 23 (2155 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

Hey,

Use a single variable for row and a single variable for column:


Code
my $row = 0; 
my $col = 0;


Every time in your code you want to go to the next row or column, just + 1 to the variable, e.g.:


Code
$worksheet->write($row, $col, $cr_line); 
$row++;
$worksheet->write($row, $col, $_);
$row++;


Chris


(This post was edited by Zhris on Aug 19, 2010, 9:19 PM)


iphone
User

Aug 19, 2010, 9:48 PM

Post #10 of 23 (2149 views)
Re: [Zhris] Moving around lines in a file [In reply to] Can't Post

Thanks ,I figured that out.

Can someone pls explain me the below line,what does it to and what is xms modifier for?please

Input
//deploy/core/ssm/ssl/main/latest/src/spreadsheet.c#2 - edit change 972508 (ktext)

Output
spreadsheet.c (if am not wrong)


Code
/([^\\\/]+ \. (?:min?:cfg|c|h|s)) [\s#]/xms;



(This post was edited by iphone on Aug 19, 2010, 10:08 PM)


BillKSmith
Veteran

Aug 20, 2010, 4:17 PM

Post #11 of 23 (2110 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

You must have missed my previous post about elsif.

I have never attempted an OLE program before. I have now merged your directory spreadsheet with my CR example in the way I that I outlined before. The resulting spreadsheet does not make much sense, but it does demonstrate one way to control the display of your variables.

Code
use strict; 
use warnings;
use Win32::OLE;
my $file = "MyTest.xls";
my $excel = Win32::OLE->GetActiveObject('Excel.Application');
unless ($excel) {
$excel = new Win32::OLE( 'Excel.Application', \&QuitApp )
or die "Could not create Excel Application object";
}
$excel->{Visible} = 1;
$excel->{SheetsInNewWorkBook} = 1;
my $workbook = $excel->Workbooks->Add();
my $worksheet = $workbook->Worksheets(1);
$worksheet->{Name} = "CR LINES";
my $cr_line = '';
my $cellrow = 1;
my $range = $worksheet->Range("A$cellrow:B$cellrow");
$range->{Value} = [ 'CT', 'DATA/CASE' ];
$cellrow++;
while (<DATA>){
if (/CR/){
$cr_line = $_;
}
elsif (/DATA|CASE/){
if ($cr_line) {
# print $cr_line;
$range = $worksheet->Range("A$cellrow:A$cellrow");
$range->{Value} = [ $cr_line ];
$cellrow++;
$cr_line = '';
}
# print $_;
$range = $worksheet->Range("B$cellrow:B$cellrow");
$range->{Value} = [ $_ ];
$cellrow++;
}
}

$workbook->SaveAs($file);
sub QuitApp { my ($object) = @_; $object->Quit(); }


__END__
MY DATA
Return (CR)
More DATA
any text
In any CASE
another CR
something
this CR
stuff
just in CASE

Good Luck,
Bill


iphone
User

Aug 21, 2010, 11:50 AM

Post #12 of 23 (2101 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

Bill,

Thanks a lot for helping out.I have attached a screen shot of my output.One of the column contains entries like

/* Fix for Case#126543/CR#63989
/*CR 63990*/


I only want to keep the CR and the number.I want to filter out everything else in this column and my output should look like

CR 63989( or CR#63989)
CR 63990

Basically i only want CR numbers in that column,Can you please guide me?
The below code is working for me currently.So,I want to keep using this,I need to modify the below code

Code
    #!/usr/bin/perl -w 

use strict;
use Spreadsheet::WriteExcel;



my $i = 0;

# Create a new Excel workbook
my $workbook = Spreadsheet::WriteExcel->new("perl.xls");
my $worksheet = $workbook->addworksheet();

my $cr_line = '';
open my $line, '<', 'features.txt' or die 'Cannot open file2';

while( <$line> ){

if (/CR/){
$cr_line = $_;
}
elsif (/DATA|CASE/i){

$worksheet->write($i, 0, $cr_line);
$worksheet->write($i, 1 , $_);
$cr_line = '';
$i++;

}
}

$workbook->close();
Attachments: CR.JPG (42.1 KB)


BillKSmith
Veteran

Aug 21, 2010, 12:40 PM

Post #13 of 23 (2098 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post


Code
    if (/CR/){ 
$cr_line = $_;
$cr_line =~ s/\A.* # Match anything before CR
CR # Match CR
[^\d]+ # Match atleast one non-digit after CR
(\d+) # Match and save the number
.* # Match the rest of the line
/CR $1/xms; # Replace match with 'CR' & num
}

Good Luck,
Bill


iphone
User

Aug 21, 2010, 1:22 PM

Post #14 of 23 (2092 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

Thanks a lot for the quick reply.

I still see entry's like/* Case180598/CR189264 */ this -->Can these entries also be converted to CR189264


BillKSmith
Veteran

Aug 21, 2010, 1:46 PM

Post #15 of 23 (2089 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post


Code
  

[^\d]+ # Match atleast one non-digit after CR

[^\d]* # Match possible non-digits after CR



Your sample lilne contains both 'CR' and 'Case'. Are you sure you are handling this correctly?
Good Luck,
Bill


iphone
User

Aug 21, 2010, 2:08 PM

Post #16 of 23 (2087 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

Actually I want both 'Case' and 'CR' but when we use ,the below match

Code
                       [^\d]+        # Match atleast one non-digit after CR  

/*Case# 164422 CR# 184271*/ --->Getting printed as CR 184271
but
/* Case162083/CR184631 */ --> printed as is

Can /*Case# 164422 CR# 184271*/ also be printed "as is"?


BillKSmith
Veteran

Aug 21, 2010, 7:46 PM

Post #17 of 23 (2065 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

The short answer is 'yes', but the case data will be in the wrong cell. Also consider that if the next line had been a pure CR line, this line would not have been printed at all! Frown I think that it is time to correct your requirements before you change the code again.
Good Luck,
Bill


iphone
User

Aug 21, 2010, 9:15 PM

Post #18 of 23 (2057 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post

 
Sure,One question when we use the below match

Code
                       [^\d]+        # Match atleast one non-digit after CR   

Why is

/*Case# 164422 CR# 184271*/ --->Getting printed as CR 184271
but
/* Case162083/CR184631 */ --> printed as is

Please explain


BillKSmith
Veteran

Aug 22, 2010, 11:07 AM

Post #19 of 23 (2051 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

The second case does not match the pattern.


Quote

Code
                       [^\d]+        # Match atleast one non-digit after CR





Good Luck,
Bill


iphone
User

Aug 22, 2010, 12:39 PM

Post #20 of 23 (2048 views)
Re: [BillKSmith] Moving around lines in a file [In reply to] Can't Post


Code
But why? 

/*Case# 164422 CR# 184271*/ --->This also has a non-digit
but
/* Case162083/CR184631 */ --> This also has a non digit


In Reply To



BillKSmith
Veteran

Aug 22, 2010, 1:19 PM

Post #21 of 23 (2045 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

The character '1' after the 'R' of 'CR' is a digit (clearly not a non-digit). All the other examples, that I have seen, have the character '#' and/or white-space after the 'R'. My regular expression generalized that to 'non-digits' and documented it with comments. You will never be able to write an error free program until you have a complete and accurate specification of the data!
Good Luck,
Bill


iphone
User

Sep 1, 2010, 12:47 PM

Post #22 of 23 (2005 views)
Post deleted by iphone [In reply to]

 


BillKSmith
Veteran

Sep 2, 2010, 6:17 AM

Post #23 of 23 (1994 views)
Re: [iphone] Moving around lines in a file [In reply to] Can't Post

The variety of formats in your sample input is far beyond my ability to parse with a single regular expression. I suggest that you write a subroutine that identifies the format before attempting to parse it. This would give you a systematic way to add new formats as they appear (they surely will).
Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives