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:
Searching for a string

 

First page Previous page 1 2 3 Next page Last page  View All


Tejas
User

Jan 28, 2015, 11:56 PM

Post #26 of 51 (7918 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Can u please post your code and error


mohan
User

Jan 29, 2015, 12:53 AM

Post #27 of 51 (7916 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post

Actually the above code works !

but throws few errors :

Unquoted string "mydir" may clash with future reserved word at C:\Perl64\bin\sam
ple1.pl line 12.
Unquoted string "mydir" may clash with future reserved word at C:\Perl64\bin\sam
ple1.pl line 13.

Adding the code :

use strict;
use warnings;

use Cwd;

my $Directoryname = getcwd();

print "My Current Dir is $Directoryname \n";

my @files;

opendir(mydir, $Directoryname) or die "cannot open directory $Directoryname";
@files = map { "$Directoryname/$_" } grep(/\.css$/,readdir(mydir));

foreach my $file (@files) {
open my $handle, '<', $file or die "could not open '$file': $!";
while (my $line = <$handle>) {

if ($line =~ /font-size/) {
if($line !~ /%/){
print "\n Forced Font is detected. -- $line\n";
}
else {
print "\n Font is specified in % -- $line \n"
}
}

if ($line =~ /line-height/) {
print "\n Forced Line-height is detected. \n";
}


if ($line =~ /position:absolute/) {
print "\n position:absolute is detected. \n";
}

}
close($handle);
}


(This post was edited by mohan on Jan 29, 2015, 12:54 AM)


Tejas
User

Jan 29, 2015, 1:04 AM

Post #28 of 51 (7909 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

They are warnings but not errors
Try to apply Laurent or fishmongers recommendations for reading files in directory using glob

That is the more efficient way of accessing the files from a directory than the code I be posted

I would want u to remove the map that Iam using and change it to the way Laurent and fishmonger wanted .
And please post the updated code
If u find trouble in changing please ask

Use this


Code
for my $file (<*.css>) {


Instead of our for loop or try using glob

Thanks


(This post was edited by Tejas on Jan 29, 2015, 1:07 AM)


mohan
User

Jan 29, 2015, 1:13 AM

Post #29 of 51 (7903 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post

used laurent's suggestion and there was no warning seen and the O/P was correct.

Code :

use strict;
use warnings;

use Cwd;


my $dir = getcwd();
my @files = glob("$dir/*.css");

for my $file (@files) {
open my $handle, '<', $file or die "could not open '$file': $!";
while (my $line = <$handle>) {

if ($line =~ /font-size/) {
if($line !~ /%/){
print "\n Forced Font is detected. -- $line\n";
}
else {
print "\n Font is specified in % -- $line \n"
}
}

if ($line =~ /line-height/) {
print "\n Forced Line-height is detected. \n";
}


if ($line =~ /position:absolute/) {
print "\n position:absolute is detected. \n";
}

}
close($handle);
}


Tejas
User

Jan 29, 2015, 1:15 AM

Post #30 of 51 (7897 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Sure,u can also try the below too
for my $file (<*.css>)


And I thought u wanted to end the loop if you see these patterns once
Is it not the case
Because with this code I'll keep looping till the end of file

Thanks
Tejas


mohan
User

Jan 29, 2015, 1:19 AM

Post #31 of 51 (7896 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post

Yes pls ! ..I don't want it to keep on running and flood the cmd and also wanna throw a message if there is no CSS files found in the cwd .


Zhris
Enthusiast

Jan 29, 2015, 8:39 AM

Post #32 of 51 (7869 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Hi,

I see you have already received plenty of help with your problem, but wanted to provide the approach I would take. My version uses an operations array, where each element is a hash made up of a label ( in order to identity the test ), a test ( a code ref which accepts the line as an argument and returns either true or false indicating if the test passed or failed ), and a count ( dynamically added to the hash or reset while iterating over each file and incremented each time a test passes ). I find this approach more manageable than a group of conditions with individual count variables.


Code
use strict; 
use warnings;
use Cwd;

my @operations =
(
{
label => 'non percentile font size',
test => sub { $_[0] =~ /font-size\s*(:|=)\s*[^%]+$/ },
},
{
label => 'line height',
test => sub { $_[0] =~ /line-height/ },
},
{
label => 'position absolute',
test => sub { $_[0] =~ /position\s*(:|=)\s*absolute/ },
},
);

my $dirpath = getcwd;

my @filepaths = glob( "$dirpath/*.css" );

print "no css files\n" unless @filepaths;

for my $filepath ( @filepaths )
{
print "\n>>> $filepath <<<\n";

$_->{count} = 0 for ( @operations ); # set or reset counts.

open my $filehandle, '<', $filepath or die "could not open '$filepath': $!";

while ( my $line = <$filehandle> )
{
$_->{test}->( $line ) and $_->{count}++ for ( @operations ); # for each operation, call the test and increment count if it returns true.
}

close $filehandle;

print "$_->{label} occurred $_->{count} times\n" for ( @operations ); # for each operation, print the outcome.
}


Regards,

Chris


(This post was edited by Zhris on Jan 30, 2015, 6:56 AM)


Laurent_R
Veteran / Moderator

Jan 29, 2015, 11:01 AM

Post #33 of 51 (7815 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post


In Reply To
Hi
I have used lexical dir handle
Can u please tell me where is the issue
Or am I confused about what a lexical dir handle is


Here:

Code
opendir(mydir, $Directoryname) or die "cannot open directory $Directoryname";

"mydir" is a bareword dir handle. It is better to use something like this:

Code
opendir(my $dir, $Directoryname) or die "cannot open directory $Directoryname";

and the use $dir for reading the directory.


mohan
User

Jan 29, 2015, 9:59 PM

Post #34 of 51 (7776 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

I just tried this code and it's just awesome !! But when I convert it into .exe file using perlApp and run it, I can just see the cmd flashing for a microsecond and disappearing..is it possible to make the cmd stay unless we select the "ESC" key? (NOTE: I tried using the print screen and captured it..the file is running correctly just the cmd is closing out in less than a second)


(This post was edited by mohan on Jan 29, 2015, 10:01 PM)


mohan
User

Jan 29, 2015, 10:11 PM

Post #35 of 51 (7773 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Added this and it works fine now :)

END {
print "Press enter to exit\n";
<>;
}


mohan
User

Jan 30, 2015, 2:53 AM

Post #36 of 51 (7759 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

Can you please help with one more thing here ?

The code posted below :


Code
use strict;  
use warnings;
use Cwd;

my @operations =
(
{
label => 'Harcoded font size value !!',
test => sub { $_[0] =~ /font-size\s*(:|=)\s*[^%]+$/ },
},
{
label => 'Forced Line height value !!',
test => sub { $_[0] =~ /line-height/ },
},
{
label => 'position absolute !!',
test => sub { $_[0] =~ /position\s*(:|=)\s*absolute/ },
},

{
label => 'Forced font color found !!',
test => sub { $_[0] =~ /color/ },
},
);

my $dirpath = getcwd;

my @filepaths = glob( "$dirpath/*.css" );

print "no css files\n" unless @filepaths;

for my $filepath ( @filepaths )
{
print "\n>>> $filepath <<<\n";

$_->{count} = 0 for ( @operations ); # set or reset counts.

open my $filehandle, '<', $filepath or die "could not open '$filepath': $!";

while ( my $line = <$filehandle> )
{
$_->{test}->( $line ) and $_->{count}++ for ( @operations ); # for each operation, call the test and increment count if it returns true.
}

close $filehandle;

print "$_->{label} $_->{count} Instance found\n" for ( @operations ); # for each operation, print the outcome.
}
END {
print "Press enter to exit\n";
<>;
}


Searches for all CSS files.

I need similar patter for files with "opf" extension as well...Can I just copy paste the same code ? Also, I need to use specific conditions when the search is carried out for "opf" files. They are:

1. Search for "language" keyword. If found print that line.
2. Search for "layout-get" and "fixed-get". If either of this is found then print "get" is found or if none of this is found then "print no get is found".

I don't need the "instance" count here since the "opf" file won't have the same keywords repeated many times


Zhris
Enthusiast

Jan 30, 2015, 6:55 AM

Post #37 of 51 (7744 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Hi,


Quote
Can I just copy paste the same code


Do your new requirements need to be combined into the same script, or are two separate scripts desirable?

Chris


mohan
User

Jan 30, 2015, 7:41 AM

Post #38 of 51 (7736 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

Combining it in the same script would be great !


Zhris
Enthusiast

Jan 30, 2015, 9:31 AM

Post #39 of 51 (7722 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Hi,

Upon combining, the script becomes quite complex due to the significant variations between each file type and/or each operation. Personally at this stage I might consider repeating sections of code or rewriting object orientatedly with file type specific classes and to some extent operation specific classes. Nonetheless, lets continue with a "definitions" data structure.

Firstly, I haven't supported short circuiting, in other words, for opf files once all operations have been achieved there is no point in reading the rest of the file. There are numerous ways this could be implemented if desired, which I'll leave to you. For now i.e. for language, the last line found is the one printed, although you mentioned there are no duplicates anyway.

The operations array has been replaced with a filedefs array. Each element is a hash which describes how to handle each file type. The action to be performed before processing the file, if a test passes and after processing the file, are now coderefs under preaction, testaction and postaction respectively. If you need an operation specific action, you can override by putting the action under a specific operation i.e. layout or fixed get postaction.


Code
use strict; 
use warnings;
use Cwd;

my @filedefs =
(
{
extension => 'css',
operations =>
[
{
label => 'Harcoded font size value',
test => sub { $_[1] =~ /font-size\s*(:|=)\s*[^%]+$/ },
},
{
label => 'Forced Line height value',
test => sub { $_[1] =~ /line-height/ },
},
{
label => 'position absolute',
test => sub { $_[1] =~ /position\s*(:|=)\s*absolute/ },
},
{
label => 'Forced font color',
test => sub { $_[1] =~ /^\s*color\s*(:|=)/ },
},
],
preaction => sub { $_[0]->{count} = 0 },
testaction => sub { $_[0]->{count}++ },
postaction => sub { print "$_[0]->{label} !! $_[0]->{count} Instance found\n" },
},
{
extension => 'opf',
operations =>
[
{
label => 'language',
test => sub { $_[1] =~ /language/ },
},
{
label => 'layout or fixed get',
test => sub { $_[1] =~ /(layout|fixed)-get/ },
postaction => sub { print +( defined $_[0]->{line} ) ? 'get is found' : 'no get is found', "\n" }
},
],
preaction => sub { $_[0]->{line} = undef },
testaction => sub { $_[0]->{line} = $_[1] },
postaction => sub { print $_[0]->{line} if defined $_[0]->{line} },
#shortcircuit => 1,
}
);

my $dirpath = getcwd;

for my $filedef ( @filedefs )
{
my @filepaths = glob( "$dirpath/*.$filedef->{extension}" );

print "\nno $filedef->{extension} files\n" unless @filepaths;

for my $filepath ( @filepaths )
{
print "\n>>> $filepath <<<\n";

for my $operation ( @{$filedef->{operations}} )
{
my $preaction = $operation->{preaction} // $filedef->{preaction};

$preaction->( $operation );
}

open my $filehandle, '<', $filepath or die "could not open '$filepath': $!";

while ( my $line = <$filehandle> )
{
for my $operation ( @{$filedef->{operations}} )
{
my $test = $operation->{test};
my $testaction = $operation->{testaction} // $filedef->{testaction};

$test->( $operation, $line ) and $testaction->( $operation, $line );
}
}

close $filehandle;

for my $operation ( @{$filedef->{operations}} )
{
my $postaction = $operation->{postaction} // $filedef->{postaction};

$postaction->( $operation );
}
}
}

END
{
print "\nPress enter to exit\n";
<>;
}


Regards,

Chris


(This post was edited by Zhris on Jan 30, 2015, 9:57 AM)


mohan
User

Feb 2, 2015, 1:14 AM

Post #40 of 51 (7573 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

Whoooooohhh !! That's one hell of a code there !! I wish I could use some of your brainCool

This code works absolutely fine, but I need some little modification to be done in the keywords !! sorry for that :

1. Search for "language" keyword. If found print that line. (Here the "language" keyword can be repeated multiple times and I want all the instance to be printed)
2. Search for "layout-get" and "fixed-get". If either of this is found then print "get" is found or if none of this is found then "print no get is found". (Instead of "layout-get" and "fixed-get" the keywords are "pre-paginated" and "name="fixed-layout" content="true""


Zhris
Enthusiast

Feb 2, 2015, 6:12 PM

Post #41 of 51 (7552 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Hi,

After I last posted, I modified the code slightly to support short circuiting ( via operation attribute "done" ), chomping the line ( in case printing last line which doesn't have newline ) and have compacted a few of the blocks into a single line ( personal preference ). I will use this version instead, although its a little less readable. Fundamentally, in order to support your requirement adjustments, I modified the @filedefs array so that each of the opf operations have their own set of action coderefs that do the desirable thing accordingly.


Code
use strict; 
use warnings;
use Cwd;

my @filedefs =
(
{
extension => 'css',
preaction => sub { $_[0]->{count} = 0 },
testaction => sub { $_[0]->{count}++ },
postaction => sub { print "$_[0]->{label} !! $_[0]->{count} Instance found\n" },
operations =>
[
{
label => 'Harcoded font size value',
test => sub { $_[0] =~ /font-size\s*(:|=)\s*[^%]+$/ },
},
{
label => 'Forced Line height value',
test => sub { $_[0] =~ /line-height/ },
},
{
label => 'position absolute',
test => sub { $_[0] =~ /position\s*(:|=)\s*absolute/ },
},
{
label => 'Forced font color',
test => sub { $_[0] =~ /^\s*color\s*(:|=)/ },
},
],
},
{
extension => 'opf',
operations =>
[
{
label => 'language',
test => sub { $_[0] =~ /language/ },
testaction => sub { print "$_[1]\n" },
},
{
label => 'layout or fixed get',
test => sub { $_[0] =~ /(pre-paginated|\Qname="fixed-layout" content="true"\E)/ },
testaction => sub { $_[0]->{done} = 1 },
postaction => sub { print +( $_[0]->{done} ) ? 'get is found' : 'no get is found', "\n" },
},
],
}
);

my $dirpath = getcwd;

for my $filedef ( @filedefs )
{
my @filepaths = glob( "$dirpath/*.$filedef->{extension}" );

print "\nno $filedef->{extension} files\n" unless @filepaths;

for my $filepath ( @filepaths )
{
print "\n>>> $filepath <<<\n";

do { $_->{done} = 0; $_->{preaction} // $filedef->{preaction} // sub { } }->( $_ ) for ( @{$filedef->{operations}} );

open my $filehandle, '<', $filepath or die "could not open '$filepath': $!";

while ( my $line = <$filehandle> )
{
# note the below two lines could be handled more efficiently in a testaction, which
# returns a true or false value to indicate if last etc, because its unnecessary to check
# for every line.
my @operations = grep { not $_->{done} } @{$filedef->{operations}};
last unless @operations;

chomp $line;

do { $_->{test} // sub { 0 } }->( $line ) and do { $_->{testaction} // $filedef->{testaction} // sub { } }->( $_, $line ) for ( @operations )
}

close $filehandle;

do { $_->{postaction} // $filedef->{postaction} // sub { } }->( $_ ) for ( @{$filedef->{operations}} );
}
}

END
{
print "\nPress enter to exit\n";
<>;
}



Quote
Whoooooohhh !! That's one hell of a code there !!]


It is indeed one hell of a code and covers some more advanced aspects of Perl. As briefly mentioned previously, the aim was to write a more manageable code that supports all your current requirements and potential variations in the future. It is important that you understand what it is doing in order to modify it yourself in the future. If there is anything you don't understand feel free to ask about it. You may wish to use it as a basis to develop the simpler approach that tejas provided instead.

Regards,

Chris


(This post was edited by Zhris on Feb 2, 2015, 8:17 PM)


mohan
User

Feb 2, 2015, 11:55 PM

Post #42 of 51 (7534 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

Awesome !!It's works perfectly !!

Thanks a million and tejas too, for helping out !!

I would love to learn code this way !! Any particular advice on how to proceed ? I just have the basic knowledge !


Zhris
Enthusiast

Feb 3, 2015, 8:51 AM

Post #43 of 51 (7522 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Hi,

No problem.

My style of coding comes from experience. There's always more than one way to do the same thing in Perl, over time you will broaden your knowledge and ability to code most appropriately for a particular problem. The key aspects we are dealing with here specifically are nested data structures and code references. My advice on how to proceed is to read through the O'Reilly range of Perl books and Modern Perl while regularly trying to apply your gained knowledge by solving fictitious problems. If you have an active interest in Perl, following Perl forums exposes you to a mixture of problems of all shapes and forms, which you can try and solve yourself then compare your solution with those who answered.

Goodluck,

Chris


mohan
User

Feb 8, 2015, 9:38 PM

Post #44 of 51 (7448 views)
Re: [Zhris] Searching for a string [In reply to] Can't Post

Thanks for the advice !! :) Will get in touch with you in case of any doubts :)


Tejas
User

Feb 16, 2015, 1:25 AM

Post #45 of 51 (7228 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

Zhris's solutions would always make u learn new things for solving our problem.
Understand what he has been doing all through the code, rather than just using it for a purpose.
There is a lot of perl stuff he is doing which i assume u already figured .

Thanks
Tejas


Laurent_R
Veteran / Moderator

Feb 16, 2015, 9:54 AM

Post #46 of 51 (7219 views)
Re: [mohan] Searching for a string [In reply to] Can't Post


In Reply To
Awesome !!It's works perfectly !!

Thanks a million and tejas too, for helping out !!

hanks to me.

You might also have extended your thanks to me. Wink


mohan
User

Feb 18, 2015, 1:16 AM

Post #47 of 51 (7179 views)
Re: [Laurent_R] Searching for a string [In reply to] Can't Post

Oh my bad ! Very sorry...don't know how I missed your name ! Thanks a lot :)


mohan
User

Feb 18, 2015, 1:24 AM

Post #48 of 51 (7178 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post

Sure !


Tejas
User

Feb 18, 2015, 1:28 AM

Post #49 of 51 (7177 views)
Re: [mohan] Searching for a string [In reply to] Can't Post

All I know in Perl is just because of Laurent ,chris ,bill and fishmonger
They are the four persons behind everything that I have done .
They have solved lots of problems Which I thought would never be done so easily.

Thanks


mohan
User

Feb 19, 2015, 12:27 AM

Post #50 of 51 (7159 views)
Re: [Tejas] Searching for a string [In reply to] Can't Post

Whoa ! That's great to hear ! Hope they can support and train me as well ! Smile

First page Previous page 1 2 3 Next page Last page  View All
 
 


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

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