Archive

Posts Tagged ‘perl’

Perl – Writing to file outputting in UTF-16 instead of UTF-8

September 16, 2011 2 comments

Recently I needed to write a perl script that ran on Cygwin. My default setting means that any files written by perl were being written in UTF-16. This led to what appeared to be a lot of Japanese writing, making it completely illegible and unusable.

After a lot of digging around on the internet, I managed to hack together the following code:

open my $SH, ">>:raw:encoding(UTF16-LE):crlf:utf8", "test1.txt";;
print $SH "\x{FEFF}";
print "Some test writing \n";
close ($SH);

This code tells perl we’re going to pass “characters” to this file handle instead of bytes. Next transform \n into \r\n to give DOS line endings. Next apply the UTF16-LE, so that 0x0A becomes 0x0A 0x00. This stops perl writing a byte order mark (BOM) at the beginning of the file. Finally, the raw:encoding removes the default ctrf so that it is not in the wrong place.

Now the file is being opened with the correct coding, we need to write the BOM to the beginning of the file to tell readers of this file what endianness it is. We do this by printing \x{FFF} to the file.

Perl – Oracle SQL – pass sql output into a perl variable


It is possible to run a sql command to retrieve results to an array without using the DBI or DBD modules of perl.
The following script (kr.pl) connects to sqlplus, runs a pre-written sql file to get the owner and table_name from dba_tables, puts this into an array in perl, then perl processes the array into a hash of has arrays, finally printing out a list of tables and owners. This is just an example of how perl can be used along with sqlplus to retrieve data from the database. We could take the perl script further and manipulate the data within the hash of hash array, but that is beyond the scope of this post.

#!/usr/bin/perl
@test = `sqlplus -S \/ as sysdba \@kr.sql`;
my $count = 0;
foreach my $value (@test){
my ($table_name, $owner) = split(/#/,$value);
$count++;
if (! defined %testarray) {
%testarray = ($count => {table_name=> $table_name, owner=> $owner,},);
}
else {
@testarray{$count} = {'table_name' => $table_name, 'owner' => $owner};
}
}
foreach my $table (keys %testarray) {
for my $number (keys %{ $testarray{$table}}) {
print "$number=$testarray{$table}{$number}";
}
print "\n ";
}

The sql code (kr.sql) is as follows:

set feedback off pages 0 timing off echo off
set feedback off pages 0 timing off echo off
set feedback off pages 0 timing off echo off
select table_name||'#'|| owner from dba_tables where owner = 'SYS' and table_name like '%JAVA%';
exit
~

The output of the perl script is as follows:

/home/krobbe > ./kr.pl
owner=SYS
table_name=PROCEDUREJAVA$
owner=SYS
table_name=JAVA$RMJVM$AUX2
owner=SYS
table_name=JAVA$JVM$STEPS$DONE
owner=SYS
table_name=JAVA$JVM$STATUS
owner=SYS
table_name=WRH$_JAVA_POOL_ADVICE
owner=SYS
table_name=TRIGGERJAVAF$
owner=SYS
table_name=JAVA$RMJVM$AUX
owner=SYS
table_name=JAVA$POLICY$
owner=SYS
table_name=JAVAOBJ$
owner=SYS
table_name=TRIGGERJAVAC$
owner=SYS
table_name=TRIGGERJAVAM$
owner=SYS
table_name=TRIGGERJAVAS$
owner=SYS
table_name=JAVA$RMJVM$AUX3
owner=SYS
table_name=JAVA$POLICY$SHARED$TABLE
owner=SYS
table_name=JAVASNM$
owner=SYS
table_name=JAVA$PREFS$

Perl – getOpt for retrieving command line options


If you are writing a perl script that you wish to take in arguments from the command line then you will need to use the getOpt function.

GetOpt variations

There are two versions of getOpt with perl. You can either use GetOpt::Std which will process single character switches, or you can use GetOpt::Long which will process single character switches, as well as fullname –word switches.

Getopt::Long Examples

The below example shows how a command line switch can be used:

---perl script (disc.pl)---
use warnings;
use strict;
use Getopt::Long;
my $DISC;
GetOptions (
'disc|d=s' => \$DISC
);
print "DISC = $DISC\n";

To run the script you enter the following at the command line:

$ ./disc.pl -d C

or

$ ./disc.pl --disc C

Both of these commands will pass the value “C” to the parameter “DISC”. The script will then print the value of $DISC to the screen.

The =s means that the option is a required arbitary value, if it were :s instead that would mean it is an optional arbitary value. Without the s the value is either 0 or 1 according to whether the option has been used on the command line.

If the value is a numeric you can use the i flag instead of the s flag.

Perl – Get current time without perl packages


Although perl has a built in package for getting the DateTime, you cannot guarantee that the system you are using has this package installed. Therefore in this situation it would be necessary to put the localtime into an array and work with it from there. The below script shows how to do this:

### initialize datetime my %DTTIME = ();
my ($SEC,$MIN,$HOUR,$MDAY,$MON,$YEAR,$WDAY,$YDAY,$ISDST) = localtime(time);
### format numbers
$DTTIME{year }  = sprintf "%04d",($YEAR + 1900); ## 4 digits to specify the year
$DTTIME{mon  }  = sprintf "%02d",($MON + 1); ## zeropad months
$DTTIME{mday }  = sprintf "%02d",$MDAY; ## zeropad day of the month
$DTTIME{wday }  = sprintf "%02d",$WDAY + 1;  ## zeropad day of week;sunday = 1;
$DTTIME{yday }  = sprintf "%02d",$YDAY; ## zeropad nth day of the year
$DTTIME{hour }  = sprintf "%02d",$HOUR; ## zeropad hour
$DTTIME{min  }  = sprintf "%02d",$MIN;  ## zeropad minutes
$DTTIME{sec  }  = sprintf "%02d",$SEC;  ## zeropad seconds
$DTTIME{isdst}  = $ISDST;

If you wished to then use this you could do so as follows:

print "Date = $DTTIME{mday} - $DTTIME{mon} - $DTTIME{year}";

Categories: Perl Tags: , , ,

Perl – Perl Version

October 22, 2010 5 comments

Sometimes it is necessary to find which version of perl you are running on your Linux server.

Find Perl Version

$ perl -v

Categories: Commands, Linux, Perl Tags: , ,