Harry Putnam wrote:
I'm not sure what these errors are telling me.
The script is supposed to remove dups from .bash_history
Wouldn't it be simpler to set HISTCONTROL to ignoredups:
export HISTCONTROL=ignoredups
Or:
export HISTCONTROL=ignoreboth
but not operate on the last 12 lines... just reprinting them.
./uniqbh.pl
Copying ./bash_history to ./bash_history-101809_020827
Unlinking ./bash_history
Copying /tmp/lPlN3goGnI.tmp ./bash_history
Operation "eq": no method found,
left argument in overloaded package File::Temp,
right argument has no overloaded magic at
/usr/lib/perl5/5.8.8/File/Copy.pm line 76, <BASH_HISTORY> line 18151.
------- 8< snip ---------- 8< snip ---------- 8<snip -------
#!/usr/bin/perl
use strict;
use warnings;
# my $BashHistory = "$ENV{'HOME'}/.bash_history";
my $BashHistory = "./bash_history";
my $data = '';
my %data;
my $ext = '.tmp';
## Creat an honest to goodness random tmp file name
require File::Temp;
use File::Temp ();
Those two lines both do the same thing. Pick *one*.
# [HP 101709_220324 Unlink is set to 1 by default .. that
# means it will be unlinked when the object goes out of scope
# so setting it to 0 means I have to delete (unlink) it manually
my $tmpfile = new File::Temp( UNLINK => 0, SUFFIX => '.tmp' );
Usually written as:
my $tmpfile = File::Temp->new( UNLINK => 0, SUFFIX => '.tmp' );
open(TMPFILE,">$tmpfile") or die "Can't open $tmpfile: $!";
Why are you opening the file again? You already have a writable
filehandle in $tmpfile.
## Keep this many lines from being processed, but do include them
## in the final file.
my $KeepLines = 12;
my $ProcessLines = (count_lines($BashHistory) - $KeepLines);
##### BEGIN Body ##### ##### #####
open(BASH_HISTORY,"<$BashHistory")or die "Can't open $BashHistory: $!";
while (<BASH_HISTORY>) {
chomp;
## Process all but $KeepLines
if($. <= $ProcessLines){
## finds unique input lines and prints them to a separate file
if ($data{$_}++ == 0) {
print TMPFILE $_ . "\n";
Why chomp the newlines off and then just add them back on again?
}
}elsif($. > $ProcessLines){
print TMPFILE $_ . "\n";
}
}
open my $BASH_HISTORY, '<', $BashHistory or die "Can't open
$BashHistory: $!";
while ( <$BASH_HISTORY> ) {
## Process all but $KeepLines
if ( $. <= $ProcessLines ) {
## finds unique input lines and prints them to a separate file
next if $data{ $_ }++;
}
print $tmpfile $_;
}
close(TMPFILE);
use File::Copy;
print "Copying $BashHistory to ".$BashHistory."-". PaddedDateStr()."\n";
copy( $BashHistory, $BashHistory . "-" . PaddedDateStr() )
or die "Copy failed: $!";
print "Unlinking $BashHistory\n";
unlink $BashHistory;
unlink $BashHistory or die "unlink failed: $!";
print "Copying $tmpfile $BashHistory \n";
copy( $tmpfile, $BashHistory )
or die "Copy failed: $!";
print "Unlinking $tmpfile\n";
unlink $tmpfile;
unlink $tmpfile or die "unlink failed: $!";
##### BEGIN sub functions ##### #####
sub count_lines {
my $file = shift;
open my $fh, "<", $file
or die "could not open $file:$!";
my $lines = 0;
$lines++ while <$fh>;
return $lines;
}
perldoc -q "How do I count the number of lines in a file?"
sub PaddedDateStr {
my ($mon,$mday,$year,$hour,$min,$sec,$wday) = (localtime(time))[4,3,5,2,1,0,6];
# $year += 1900; ## prints 2005
$year -= 100; ## prints 05 (with %02d)
If you were writing this ten years ago you would now have a negative
number in $year. If this is still in use one hundred years from now you
will now have a three digit number in $year. Use modulus instead.
$mon += 1;
my $PaddedDateStr = sprintf "%02d%02d%02d%s%02d%02d%02d",
$mon,$mday,$year,"_",$hour,$min,$sec;
return $PaddedDateStr;
}
Or just:
sub PaddedDateStr {
my ( $sec, $min, $hour, $mday, $year ) = localtime;
return sprintf '%02d%02d%02d_%02d%02d%02d', $mon + 1, $mday, $year
% 100, $hour, $min, $sec;
}
But why are you using Month-Day-Year order? Your file names would sort
better in Year-Month-Day order.
Or use the POSIX::strftime function:
use POSIX 'strftime';
sub PaddedDateStr {
return strftime '%m%d%y_%H%M%S', localtime;
}
This may work better for you:
#!/usr/bin/perl
use strict;
use warnings;
use Fcntl qw/ :seek :flock /;
use POSIX qw/ strftime /;
use File::Copy;
# my $BashHistory = "$ENV{HOME}/.bash_history";
my $BashHistory = 'bash_history';
my $newBashHistory = "$BashHistory-" . strftime '%m%d%y_%H%M%S', localtime;
my $KeepLines = 12;
print "Copying $BashHistory to $newBashHistory\n";
copy( $BashHistory, $newBashHistory ) or die "Copy failed: $!";
open my $FH, '+<:raw', $BashHistory or die "Cannot open '$BashHistory' $!";
flock $FH, LOCK_EX or die "Cannot flock '$BashHistory' $!";
my @lines = <$FH>;
my @keep = splice @lines, -$KeepLines;
my %unique = map { $_ => 1 } @keep;
seek $FH, 0, SEEK_SET or die "Cannot seek '$BashHistory' $!";
truncate $FH, 0 or die "Cannot truncate '$BashHistory' $!";
print $FH grep( !$unique{ $_ }++, @lines ), @keep;
close $FH or die "Cannot close '$BashHistory' $!";
__END__
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/