Sunday, July 24, 2011

To join all the content of the file into a scalar perl


Content of the list.txt:

hello gopal,how are you,
hello james,how are you
hello,how are you,
hello Thomas,how are you,
hello Manjula,how are you,
hello karthik,how are you

Content of the Perl file:

$ddd=getfile("list.txt");
print $ddd;
 sub getfile {
          my $filename = shift;
          local *F;
          open F, "< $filename" or die "Couldn't open `$filename': $!";
          local $/ = undef;           # Read entire file at once
          $contents = <F>;            # Return file as one single `line'
          close F;
          return $contents;
        }

output:


G:\perl_programs>perl perl_filehandle.pl
hello gopal,how are you,
hello james,how are you
hello,how are you,
hello Thomas,how are you,
hello Manjula,how are you,
hello karthik,how are you
G:\perl_programs>

Analysis:
Here the entire content of the file is joined into a scalar by changing the input record separator("$/")  to be undef which is by default to "\n".By using the local scope to the record separator the change is visible only in the subroutine getfile.

Scope in Perl

Scope avaible in perl:
1)my
2)local
3)our

my scope:
1)By this scope we mean that variables defined with my are accessible only within the block
and it is not even accessible for the functions called from the block.
2)here it creates a lexical scope for the variable(only accessible within the block)
3)it is more preferrable than the other scope as it does not overwrite the value .
4)it makes a variable private in lexical scope.

local scope:
1)Here the temp variable is created in the dynamic scope.
2)The dynamic scope it means the variable not only visible within the block but it is also visible in the function called from the block.
3)it is mainly used in cases where using "my" may prove illegal especially for special variables.
4)it makes variable private in a dynamic scope.

our scope:
1)It is definitely not private and it is the default thing which is used when you don't specify any scope;
2)it is global
3)Even outside the package it can be accessed by using Packagename::variablename;


Example:
Content of Perl file:


firstSub("AAAAA", "BBBBB");
sub firstSub{

local ($firstVar) = $_[0];

my($secondVar) = $_[1];
print("firstSub: firstVar = $firstVar\n");
print("firstSub: secondVar = $secondVar\n\n");
secondSub();
print("firstSub: firstVar = $firstVar\n");
print("firstSub: secondVar = $secondVar\n\n");
}
sub secondSub{
print("secondSub: firstVar = $firstVar\n");
print("secondSub: secondVar = $secondVar\n\n");
$firstVar = "ccccC";
$secondVar = "DDDDD";
print("secondSub: firstVar = $firstVar\n");
print("secondSub: secondVar = $secondVar\n\n");
}

Output:

G:\perl_programs>perl perl_scope1.pl
firstSub: firstVar = AAAAA
firstSub: secondVar = BBBBB

secondSub: firstVar = AAAAA
secondSub: secondVar =


secondSub: firstVar = ccccC
secondSub: secondVar = DDDDD

firstSub: firstVar = ccccC
firstSub: secondVar = BBBBB


Analysis:

As you may see the firstvar declared as local scope is visible in secondSub routine
But secondVar declared as my scope is not visible in the routine secondSb and it is empty.
 And the other thing you may notice is firstVar variable intialized as "ccccC" overwrites the value in the block from which it was called.But in the case of secondVar variable it is not overwritten.

Saturday, July 23, 2011

joining the lines in file using comma perl

Content of list.txt:

Hi gopal,how are you
Hi james,how are you
Hi,how are you
Hi Thomas,how are you
Hi Manjula,how are you
Hi karthik,how are you

Content of the Perl file:

#!/usr/bin/perl
use File::Copy;
open(FH,";
close(FH);
#For creating the temp file and adding the line no
open(FH1,">list.txt.bak");
$dd=join(',',@ddd); # for joining the lines in the file
$dd =~ s/\n//sg; # for removing the newline character
print FH1 $dd;
close(FH1);
move("list.txt.bak","list.txt") or die "cannot move";
# for moving the temp file to the original files
unlink("list.txt.bak") or die "cannot delete the file";
# for removing the temp file

Content of the list.txt after execution of perl file:

Hi gopal,how are you,Hi james,how are you,Hi,how are you,Hi Thomas,how are you,Hi Manjula,how are you,Hi karthik,how are you

Analysis:
Here i am trying to join all the lines of the file list.txt and separate the lines by comma.To join all the lines i have used join command and replaced "\n" with space using substution in perl.

Adding line no in the files perl

Content of the list.txt:

Hi gopal,how are you
Hi james,how are you
Hi,how are you
Hi Thomas,how are you
Hi Manjula,how are you
Hi karthik,how are you

Content of perl file:

#!/usr/bin/perl
use File::Copy;
open(FH,"<list.txt");

@ddd=<FH> ;
close(FH);
#For creating the temp file and adding the line no
open(FH1,">list.txt.bak");
$size=scalar(@ddd);
for ( $i=0;$i<$size;$i++)
{
$ddd[$i]=~ m/(.*)/;
$dd="$i: "."$1"."\n";
print FH1 $dd;
}
close(FH1);
move("list.txt.bak","list.txt") or die "cannot move";
# for moving the temp file to the original files
unlink("list.txt.bak") or die "cannot delete the file";
# for removing the temp file

Content of the list.txt after execution of the perl file:

0: Hi gopal,how are you
1: Hi james,how are you
2: Hi,how are you
3: Hi Thomas,how are you
4: Hi Manjula,how are you
5: Hi karthik,how are you

Analysis:

Here i have tried add the line no in the file list.txt.For this i have created a tmp file
list.txt.bak and added the line no in those file by using the array index and later replaced the original file list.txt with tmp file:

To match a pattern not having a word inbetween perl

To match a pattern not having a word in between

For example if you want to match a pattern "Hi [person's name],how are you" and person should not be karthik like "Hi karthik,how are you"
and the person's name can be anything else.


Content of list.txt:

Hi gopal,how are you
Hi james,how are you
Hi,how are you
Hi Thomas,how are you
Hi Manjula,how are you
Hi karthik,how are you

Content of perl file:

#!/usr/bin/perl
open(FH,")
{
if ($_=~ m/Hi\s+((?!karthik)\w)*\,how are you/ )
{
print;
}
}

Output:

G:\perl_programs>perl perl_avoidword.pl
Hi gopal,how are you
Hi james,how are you
Hi Thomas,how are you
Hi Manjula,how are you

G:\perl_programs>


Analysis:
Here the important part of it is ((?!karthik)\w)*  which specifies karthik should not be there in between but any other word can be there specified by \w


To extract all occurence of word from string perl

#To extract occurence of word from string
#To extract a occurence of word from a string it is very easy in perl.We need to search the occurence in global way.
#For example to extract all occurence of emailid from a string
Content of the perl file:

#!/usr/bin/perl
$dd='karthik karthik@gmail.com lijo lijo@gmail.com james james@gmail.com thomas thomas@gmail.com';
while ( $dd =~ /\s+(\S*\@\S*.com)\s+/g )
{
print $1."\n";
}


output:

G:\perl_programs>perl perl_occurence.pl
hellokarthik@gmail.com
lijo@gmail.com
james@gmail.com

G:\perl_programs>

Analysis:
Here i have used the pattern /\s+(\S*\@\S*.com)\s+/g  to extract all email-ids from the scalar $dd.Here g signifies globally match all the email -ids from the string. 

Tuesday, July 19, 2011

find:bad option find: path-list predicate-list error

This error happens when the wildcard character in your find command expands.
This mainly happens when you run inside a script rather than from a command prompt.
For example inside the perl program you have something like:


@files=`find . -name *C* `;

When you run this program it will through this error:
find:bad option
find:path-list predicate list

Solution to it is enclose the wildcards within single quote or double quotes like this
to prevent the error:

@files=`find . -name '*'C'*' `;
(or)
@files=`find . -name "*C*"`;