Tuesday, March 24, 2009

Error : Can't do inplace edit without backup

I am writing a command line perl program to replace text content in a file .I know that the following instruction executes successfully on one of the unix machine. I am trying to execute it through cygwin.

perl -pi -e 's/siva/prabu/g;' TestScript.xml

But I get following error.
Can't do inplace edit without backup.

I tried to run:
perl -pi 'Temp.bak' -e 's/siva/prabu/g;' TestScript.xml

It gives me
Can't open -e: No such file or directory.
Can't open s/siva/prabu/g;: No such file or directory.
Can't do inplace edit without backup.

Solution :

perl -pi.bak -e 's/siva/prabu/g;' TestScript.xml

or

perl -pi.bak -e "/siva/prabu/g;" TestScript.xml

Monday, March 23, 2009

Special Variables - @ARGV

@ARGV

Short Name : @ARGV
Scope        :          always global

This variable is an array of the arguments passed to the script. he first element of this array is the first argument (not the program name). As the arguments are processed, the value of this variable can alter.

Example:

$TestString = "There were $#ARGV arguments first arguments @ARGV[0]\n";

print $TestString;

Monday, March 16, 2009

Perl Handles Numbers

Perl can handle both whole numbers (integers, like 37) and floating-point numbers (real numbers with decimal points, like 17.5 or -235.2). Internally, Perl handles both as 'double precision floating-point values', but in Perl code they are treated the same way and can be used interchangeably. Here are some examples of number literals :

128 (positive integer)
-127 (negative integer)
0
17.5 (positive floating number)
-4.6E13 (negative 4.6 times 10 to the 13th power. E denotes exponential notation)

The last numeric literal above is an example of exponential or scientific notation, used when you need to work with very large or very small numbers.

In addition to decimal literals, Perl supports octal (base 8) and hexadecimal (base 16) literals.

Octal literals are denoted by a leading 0, and hex literals by a leading 0x or 0X.

For example:
0177 # 177 octal, same as 127 decimal
0xf0 # f0 hexadecimal, same as 240 decimal
- 0Xff # negative ff hexadecimal, same as -255 in decimal

Many people writing Perl programs will never need to work with octal or hex numbers - but be careful not to specify decimal numbers with a leading zero, because Perl will interpret them as octal.

Basic Naming Rules in Perl

  • Variable names can start with a letter, a number, or an underscore, although they normally begin with a letter and can then be composed of any combination of letters, numbers, and the underscore character.
  • Variables can start with a number, but they must be entirely composed of that number; for example, $123 is valid, but $1var is not.
  • Variable names that start with anything other than a letter, digit, or underscore are generally reserved for special use by Perl
  • Variable names are case sensitive; $foo, $FOO, and $fOo are all separate variables as far as Perl is concerned.
  • As an unwritten (and therefore unenforced) rule, names all in uppercase are constants.
  • All scalar values start with $, including those accessed from an array of hash,for example $array[0] or $hash{key}.
  • All array values start with @, including arrays or hashes accessed in slices,for example @array[3..5,7,9] or @hash{‘bob’, ‘alice’}.
  • Namespaces are separate for each variable type—the variables $var, @var, and %var are all different variables in their own right.FUNDAMENTALS In situations where a variable name might get confused with other data (such as when embedded within a string), you can use braces to quote the name. For example, ${name}, or %{hash}.
  • Limited to 255 characters, however. We hope that suffices

Tuesday, March 10, 2009

Printing a Hash

Solution 1 :

while ( ($key,$value) = each %hash ) {
print "$k => $v\n";
}

Solution 2 :

print map { "$_ => $hash{$_}\n" } keys %hash;

Solution 3 :

print "@{[ %hash ]}\n";


Solution 4 :
{
my @temp = %hash;
print "@temp";
}

Solution 5 :

foreach $key (sort keys %hash) {
print "$key => $hash{$key}\n";
}

Monday, March 9, 2009

How to Take a Hash Slice

Assign some variables of a hash to an array. i.e you want to take some of the elements from hash based on there keys into a array here is a trick

%hash = ( 1 => 'one', 2 => 'two',3 => 'three');
@array = @hash{'1','2'};



If you have a hashref and want to take the values of some keys into an array you can do the following.

$hashref = {1 => 'one', 2 => 'two', 3 => 'three'};
@array = @{%$hashref}{'1','2'};


Establishing a Default Value

# use $b if $b is true, else $c
$a = $b || $c;

# set $x to $y unless $x is already true
$x ||= $y

# use $b if $b is defined, else $c
$a = defined($b) ? $b : $c;

$foo = $bar || "DEFAULT VALUE";

$dir = shift(@ARGV) || "/tmp";

$dir = $ARGV[0] || "/tmp";

$dir = defined($ARGV[0]) ? shift(@ARGV) : "/tmp";

$dir = @ARGV ? $ARGV[0] : "/tmp";


# find the user name on Unix systems
$user = $ENV{USER}
|| $ENV{LOGNAME}
|| getlogin()
|| (getpwuid($<))[0]
|| "Unknown uid number $<";


@a = @b unless @a; # copy only if empty
@a = @b ? @b : @c; # assign @b if nonempty, else @c

Friday, March 6, 2009

Get Pathname Of Current Working Directory

Windows :

use File::Spec;
my $current_directory = File::Spec->rel2abs(".");
print $current_directory;


Unix

use Cwd;
my $current_directory = getcwd;
print "$current_directory";

use Cwd;
$dir = cwd;

use Cwd;
$dir = fastgetcwd;

use Cwd 'abs_path';
print abs_path($ENV{'PWD'});

use Cwd 'fast_abs_path';
print fast_abs_path($ENV{'PWD'});

Ordered Hashes

Perl hashes have no internal order. A hash consists of a number of "buckets''. When a record is inserted into the hash, the key is transformed, using a "hash function'', into a bucket number. The details of the hash function itself are not important, but a good hash function ensures that even very similar keys are mapped to different buckets. If too many keys map to the same bucket, then Perl has to spend a lot of time searching through that bucket for the corresponding value.

The important thing is not how Perl puts the key into the hash table but what the table gives us. To find if a value is in a hash, Perl takes the key name supplied, applies the same transformation and checks to see whether the key is in that position. This is much faster than searching through an ordered list.

However, while we often appreciate the speed in which hashes work, sometimes we want to maintain key order as well. A common solution is to create both our hash and an array. The array stores the keys in sorted order and we can then iterate through our has as required:

        my @idNumbers = qw(101 102 ... );

my %nameMapping = ( 101 => 'Siva', 102 => 'Sakthi', ... );
        foreach my $Key ( @idNumbers ) {
print "$Key : $nameMapping{$Key} \n";
}

If @idNumbers and %nameMapping are created in one place in our program and then never changed (such as could be expected for a list of months of the year) then this is a very good solution. However if our hash is likely to grow over time then we can encounter problems. What happens if a key is added to one structure but not the other?

Fortunately there are better solutions.

Tie::InsertOrderHash

        use Tie::InsertOrderHash;
        tie my %nameMapping => 'Tie::InsertOrderHash',
101 => 'Siva',
102 => 'Sakthi',
103 => 'Swetha',
104 => 'Saran',
105 => 'Darwin';
        print join(" ", keys %nameMapping), "\n";
        # prints: 101,102,103,104,105

In the above example, we're setting the hash at creation time. This is not required. We can add our values to our hash whenever we desire, just like a normal hash, further, our values can be any kind of value we can normally use in a hash.

Tie::IxHash

Tie::InsertOrderHash does not allow you to change values in your hash and keep the original ordering. Thus, as mentioned above, updating the keys in 102 will cause 102 to now appear after 105 when listing the keys.

If you want to be able to change values without changing the ordering then Tie::IxHash may be a better option.

        use Tie::IxHash;
        tie my %nameMapping => 'Tie::IxHash',
101 => 'Siva',
102 => 'Sakthi',
103 => 'Swetha',
104 => 'Saran',
105 => 'Darwin';

# Update Hash Value
$nameMapping{102} = 'Kumar';
        print join(" ", keys %nameMapping), "\n";
        # prints: 101,102,103,104,105


There is also Tie::Hash::Indexed which provides less features than Tie::IxHash, but is considerably faster.

To get a similar behaviour to Tie::InsertOrderHash you can delete a key-value pair from your hash before providing the new value. Thus if we were to write:

delete($nameMapping{102} );

$nameMapping{102} = 'KumarS';

then June would be considered to have been inserted last.


Thursday, March 5, 2009

How many ways can we express string in Perl

Many.

For example

'this is a string' can be expressed in:
"this is a string"
qq/this is a string like double-quoted string/
qq^this is a string like double-quoted string^
q/this is a string/
q&this is a string&
q(this is a string)

Tuesday, March 3, 2009

TypeGlobes

The typeglob is a composite data type that contains one instance of each other data types. It is an amalgam of all Perl’s data types, from which it gets its name. It is a sort of ‘super reference’ whose value is not a single reference to something but six slots that can contain six different references, all at once:

a.scalar – A reference to scalar
b.array – A reference to array
c.hash – A reference to hash
d.code – A reference to a subroutine
e.handle – A file or directory handle
f.format – A format definition

Defining Typeglobs:
$message = “Some text”;
*missive = *message;
print $missive; # prints “some text”;
or
*glob = \$scalar;
*glob = \@arr;
*glob = \%hash;
*glob = sub { return “\n Try this !” };

Manipulating Typeglobs:
print “\n $glob “;
print “\n @glob ”;
foreach $key (keys %glob)
{
print “\n $key => $glob{$key} “;
}
print glob();

Accessing Typeglobs:
$scalarref = *glob{SCALAR};
$arrayref = *glob{ARRAY};
$hashref = *glob{HASH};
$subref = *glob{CODE};