#!/usr/bin/perl
use strict;
use File::Copy;
use File::Temp;
my $FILENAME = "MY_FILE.txt";
dos2ux($FILENAME);
sub dos2ux {
my $infile = shift;
my $is_converted = 0;
# Make a temp file which will self delete automatically.
my $tmp = File::Temp->new(
UNLINK => 1);
if (open(INFILE, $infile)) {
if (open (OUTFILE, ">", $tmp->filename)) {
binmode(OUTFILE);
while () {
s/\r\n$/\n/;
print OUTFILE $_;
}
close(OUTFILE);
$is_converted = 1;
}
close(INFILE);
} else {
print "Fail to open $infile\n";
}
if ($is_converted) {
copy($tmp->filename, $infile);
}
}
Friday, April 13, 2012
How to Convert a file from Windows format to Linux format
This is a Perl implementation of "dos2unix" (a utility to convert Windows/DOS file format to Linux/UNIX file format.
Sunday, April 8, 2012
Remove Old Log Files with Keeping Minimum Number of Copies
It is very common that not all the application will purge their old log files. Hence, you need to purge the old log files (backup ZIP files) before the system runs out of space.
Normally, we will purge the old files based on date. If the application does not run for long time, all the log files will be purged. Sometime, we would like to keep the minimum number of old log files to find out when it was run.
The script will be based on the following conditions:
1. Keep Minimum Number of Copies - If the application does not run, we will keep the log files even they are few months old. It will not proceed to check the keep days if failed to meet this condition.
2. Keep Days - It will remove all the logs that older than the specify days. To keep up to today log, specify zero day.
Normally, we will purge the old files based on date. If the application does not run for long time, all the log files will be purged. Sometime, we would like to keep the minimum number of old log files to find out when it was run.
The script will be based on the following conditions:
1. Keep Minimum Number of Copies - If the application does not run, we will keep the log files even they are few months old. It will not proceed to check the keep days if failed to meet this condition.
2. Keep Days - It will remove all the logs that older than the specify days. To keep up to today log, specify zero day.
#!/usr/bin/perl
# $Id: purge_files.pl,v 1.4 2012/04/19 13:38:55 chinsiang Exp chinsiang $
#
use strict;
use Getopt::Long;
use POSIX;
use File::Spec;
use File::Glob;
my $VERSION = "1.0";
# 0 = keep today, 1 = keep today & yesterday, etc
my $BACKUP_DAYS_TO_KEEP = 14;
# Specify number of copies to keep. If less the this number,
# housekeeping will be aborted.
my $BACKUP_COPY_TO_KEEP = 10;
my $FILE_PATTERN = '*.log';
my %option;
die unless GetOptions(
"file-pattern=s" => \$option{'file-pattern'},
"backup-copy=i" => \$option{'backup-copy'},
"keep-days=i" => \$option{'keep-days'},
"test" => \$option{'test'},
"verbose" => \$option{'verbose'},
"help" => \$option{'help'},
);
if (defined( $option{'help'} )) {
print_usage();
}
if (!defined($option{'file-pattern'})) {
$option{'file-pattern'} = $FILE_PATTERN;
}
if (!defined($option{'backup-copy'})) {
$option{'backup-copy'} = $BACKUP_COPY_TO_KEEP;
}
if (!defined($option{'keep-days'})) {
$option{'keep-days'} = $BACKUP_DAYS_TO_KEEP;
}
if (!defined($option{'test'})) {
$option{'test'} = 0;
}
purge_files($option{'file-pattern'},
$option{'keep-days'},
$option{'backup-copy'},
$option{'test'},
$option{'verbose'});
##############################################################################
# Purge the files
sub purge_files() {
my $file_pattern = shift;
my $keep_days = shift;
my $backup_to_keep = shift;
my $test = shift;
my $verbose = shift;
my $DAY_IN_SECONDS = 86400;
my %files = get_sorted_files($file_pattern);
my $file_count = scalar(keys(%files));
my $now = time();
my $delete_time = $now - ($DAY_IN_SECONDS * $keep_days);
# Adjust to localtime 12am
$delete_time -= (($delete_time % $DAY_IN_SECONDS ) + tzoffset());
if ($verbose) {
print "Delete file older than "
. strftime("%Y-%m-%d %H:%M:%S", localtime($delete_time)) . "\n";
}
if ($verbose) {
print "Found files\n";
my $index = 0;
foreach my $file (sort { $files{$a} cmp $files{$b} } keys %files) {
$index++;
printf("%2d. %s %s\n",
$index,
$file,
strftime("%Y-%m-%d %H:%M:%S", localtime( $files{$file} ))
);
}
}
foreach my $file (sort { $files{$a} cmp $files{$b} } keys %files) {
my $file_modified = $files{$file};
if ($file_count > $backup_to_keep) {
if ($file_modified < $delete_time) {
$file_count--;
if ($test) {
print "Test: Delete $file, "
. "Modified: "
. strftime("%Y-%m-%d %H:%M:%S", localtime($file_modified))
. "\n";
}
else {
if (unlink($file) > 0) {
print "Deleted: $file, "
. "Modified: "
. strftime("%Y-%m-%d %H:%M:%S", localtime($file_modified))
. "\n";
}
}
}
}
else {
# Exit the loop
last;
}
}
}
##############################################################################
# Get sorted files into a hash table.
sub get_sorted_files {
my $path = shift;
my $regex = shift;
my @files = glob($path);
my %hash = ();
foreach my $file (@files) {
$hash{$file} = (stat($file))[9];
}
return %hash;
}
##############################################################################
# Find the timezone in seconds.
sub tzoffset {
my $t = time();
my $utc = mktime(gmtime($t));
my $local = mktime(localtime($t));
return ($local - $utc);
}
##############################################################################
# Print usage
sub print_usage {
my $usage =<<EOF
DESCRIPTION:
Purge old records
OPTIONS:
--[f]ile-pattern File pattern in regex to purge. (Default: $FILE_PATTERN)
--[b]ackup-copy Minimum backup copy to keep. (Default: $BACKUP_COPY_TO_KEEP copies)
--[k]eep-days Number of days to keep.
0 = Today, 1 = Today & Yesterday, etc.
(Default: $BACKUP_DAYS_TO_KEEP days)
--[t]est Test run without purge the files.
--[v]erbose Increase verbosity.
--[h]elp Show this help text.
EXAMPLE:
\$ $0 --keep-days 10 --backup-copy 1 --file-pattern "~/tmp/*log" --v
EOF
die($usage);
}
__END__
Wednesday, November 16, 2011
Monday, October 31, 2011
Perl Quick Start Template
When starting a new script, you can use this template as a base which consists of:
- RCS, CVS or SVN "Id" keyword to keep the version information.
- Support script arguments.
- Show usage function.
- A trim function.
#!/usr/bin/perl -w
# $Id: $
#
use strict;
use Getopt::Long;
my $VERSION = "1.0";
my %option;
die unless GetOptions(
"help" => \$option{'help'},
);
if (defined( $option{'help'} )) {
print_usage();
}
...
# Perl trim function to remove whitespace from the start and end of the string
sub trim {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
# Print usage
sub print_usage {
my $usage = <<EOF;
DESCRIPTION:
OPTIONS:
--[h]elp Show this help text.
EXAMPLE:
\$ $0
EOF
die($usage);
}
Saturday, October 8, 2011
How to Change Linux Password via SSH
Script to change Linux password remotely via SSH.
Prerequisite
For ActivePerl users, you need to download the Net::SSH2 package.
Version 5.10.x
C:\>ppm install http://cpan.uwinnipeg.ca/PPMPackages/10xx/Net-SSH2.ppd
Version 5.12.x
C:\>ppm install http://cpan.uwinnipeg.ca/PPMPackages/12xx/Net-SSH2.ppd
Scripts
#!/usr/bin/perl
use strict;
use Net::SSH2;
use Getopt::Long;
my %option = (
'server' => 'localhost',
'userid' => '',
'password' => '',
'newpassword' => '',
);
if (!GetOptions("server|s=s" => \$option{'server'},
"userid|u=s" => \$option{'userid'},
"password|p=s" => \$option{'password'},
"newpassword|n=s" => \$option{'newpassword'})) {
print_usage();
}
my $ssh2 = Net::SSH2->new();
$ssh2->connect($option{'server'}) or die "Unable to connect Host $option{'server'} \n";
$ssh2->auth_password($option{'userid'}, $option{'password'}) or die "Unable to login\n";
my $chan = $ssh2->channel();
$chan->blocking(0);
$chan->ext_data('merge');
my $cmd = "chage -l $option{'userid'}; "
. "echo -e \"$option{'password'}\\n$option{'newpassword'}\\n$option{'newpassword'}\\n\" | passwd 2>&1\n";
# print $cmd;
$chan->exec($cmd);
while (<$chan>) {
print $_;
}
#########################################################################
# Subroutines
#########################################################################
sub print_usage {
# ...
}
Saturday, April 2, 2011
Check for Holiday with Perl
In some cases we would like to avoid to execute the script during public holiday e.g. Don’t send alert during holiday. This script contains 2 functions i.e. “load_holiday_file” and “is_holiday” where you can include in your script to check for holiday.
#!/usr/bin/perl use strict; my @holidays = (); my @now = localtime(time()); my $date = sprintf("%02d-%02d-%04d", $now[3], $now[4]+1, $now[5]+1900 ); load_holiday_file(\@holidays, 'holiday.txt'); if (is_holiday(\@holidays, $date)) { print "Today is holiday"; } # Check the date is holiday # "date_to_check" is in "DD-MM-YYYY" format. sub is_holiday { my $holidays = shift; my $date_to_check = shift; my $counter = 0; my $found = 0; while($counter <= $#{holidays} && !$found) { my $holiday = $holidays->[$counter]; if ($date_to_check =~ /^$holiday/) { $found = 1; } else { $counter++; } } return $found; } # Load holiday file # Holiday file # 1. DD-MM-YYYY # 2. DD-MM (Every year on this date) sub load_holiday_file { my $holidays = shift; my $holiday_file = shift; if (open(HOLIDAY_FILE, $holiday_file)) { my $line; while (defined($line = <HOLIDAY_FILE>)) { chomp($line); next if ($line =~ /^\s*#/ ); next if ($line =~ /^$/); # Trim the string $line =~ s/^\s+//; $line =~ s/\s+$//; push @{holidays}, $line; } close(HOLIDAY_FILE); } }Holiday File
# Holiday file # 1. DD-MM-YYYY # 2. DD-MM (Every year on this date) 27-01-2011 03-02-2011 03-02-2011 22-04-2011 02-05-2011 17-05-2011 09-08-2011 30-08-2011 26-10-2011 06-11-2011 26-12-2011 02-01-2012
Sunday, September 12, 2010
Sort Date in "DD MMM YYYY" format
To sort date in "DD MMM YYYY" format (e.g. "02 DEC 2010")
#/usr/bin/perl -w
use strict;
# Constants
my %MONTH_NUMBER = (
'JAN' => 1,
'FEB' => 2,
'MAR' => 3,
'APR' => 4,
'MAY' => 5,
'JUN' => 6,
'JUL' => 7,
'AUG' => 8,
'SEP' => 9,
'OCT' => 10,
'NOV' => 11,
'DEC' => 12,
);
my @myarray = (
'08-DEC-10',
'30-NOV-10',
'26-NOV-10',
'25-NOV-10',
'25-NOV-10',
'24-NOV-10',
'11-NOV-10',
'10-NOV-10',
'10-NOV-10',
'08-NOV-10',
'03-NOV-10',
'02-NOV-10',
'01-NOV-10',
);
my @sorted_array = sort sort_func @myarray;
print "@sorted_array";
####################
# Subroutine
####################
# Sort function
sub sort_func() {
# To sort in desc, just swap $a and $b
#return convert_datenumber($b)
# cmp convert_datenumber($a);
return convert_datenumber($a)
cmp convert_datenumber($b);
}
# Convert "DD MMM YYYY" into "YYYYMMDD"
sub convert_datenumber() {
my $in_date = $_[0];
my $out_date = 0;
if (length($in_date)) {
my $day = substr($in_date, 0, 2);
my $month = $MONTH_NUMBER{ substr($in_date, 3, 3) };
my $year = substr($in_date, 7);
$out_date = $year * 10000
+ $month * 100
+ $day;
}
return $out_date;
}
Output:
01-NOV-10 02-NOV-10 03-NOV-10 08-NOV-10 10-NOV-10 10-NOV-10 11-NOV-10 24-NOV-10 25-NOV-10 25-NOV-10 26-NOV-10 30-NOV-10 08-DEC-10
Subscribe to:
Posts (Atom)