#!/usr/bin/perl -w =head1 NAME truncate-eol-whitespace - truncate white spaces at end of line. =head1 SYNOPSIS truncate-eol-whitespace [-total] [-truncated] [-nontruncated] [-dry-run] \ [file ...] [-f files-from] =head1 DESCRIPTION This program truncates extra white spaces just before end of line in specified files. File names can be specified as parameters and/or readed from specified file, '-' for STDIN. =head1 EXAMPLE Truncate all text files under DIR: find-text-files DIR -total | truncate-eol-whitespace -total -f - =cut require 5.004; use strict; use integer; use Getopt::Long; sub usage { warn "\n".join(" ", @_)."\n" if @_; warn < \$ help_option, 'total' => \$ total_option, 'truncated' => \$ truncated_option, 'nontruncated' => \$nontruncated_option, 'dry-run' => \$ dry_run_option, 'f=s' => \$ files_from_option, ) or usage; usage if $help_option; usage("no files specified") if (! defined $files_from_option) and scalar(@ARGV) < 1; my ( $total_files_checked, $total_files_empty, $total_files_truncated, $total_files_no_chars_truncated ) = (0,0,0,0,0,0,0,0,0,0); my ( $total_chars_readed, $total_chars_truncated ) = (0,0); sub truncate_file($) { my $fname = shift; $total_files_checked++; if ( ! -f $fname ) { print STDERR "is not a plain file: ".$fname."\n"; return; } if ( ! -s $fname ) { print STDERR "zero size file: ".$fname."\n"; $total_files_empty++; return; } local $/ = undef; # no records, slurp mode local *IN; open IN, "< $fname" or die "Can't open $fname: $!"; my $file = ; defined $file or die "Can't read $fname: $!"; close IN; my $length_before = length $file; $total_chars_readed += $length_before; $file =~ s/[\000-\011\013-\040]+\n/\n/mg; my $length_after = length $file; my $chars_truncated = $length_before - $length_after; die "size become greater after truncating: ".$fname if $chars_truncated < 0; if ( $chars_truncated > 0 ) { $total_files_truncated++; $total_chars_truncated += $chars_truncated; } else { $total_files_no_chars_truncated++; } if ( $chars_truncated >0 and $truncated_option ) { printf(STDOUT "%6u of %6u chars truncated from $fname\n", $chars_truncated, $length_before); } elsif ( $chars_truncated==0 and $nontruncated_option ) { printf(STDOUT "%-16s chars truncated from $fname\n", 'no'); } if ( ! $dry_run_option and $chars_truncated > 0 ) { local *OUT; open OUT, "> $fname" or die "Can't open $fname: $!"; print OUT $file or die "Can't write $fname: $!"; close OUT or die "Error on closing $fname: $!"; } } #+ main work # do process file names from the @ARGV first truncate_file($_) while defined ($_ = shift); if (defined $files_from_option) # do process file names from file|STDIN { local *IN; open (IN, $files_from_option) or die "Can't open $files_from_option: $!"; while ( my $fname = ) { chomp $fname; next if length($fname) < 1; # skip empty lines truncate_file($fname); } } #- main work format STDERR = Total files: checked empty truncated non-truncated ------- ------- ------- ------- @>>>>>> @>>>>>> @>>>>>> @>>>>>> $total_files_checked, $total_files_empty, $total_files_truncated, $total_files_no_chars_truncated Total chars truncated: @>>>>>> of @<<<<<<<<<<<<<<<<< $total_chars_truncated, $total_chars_readed . write STDERR if $total_option; exit 0; =head1 AUTHOR Dmitry Fedorov =head1 COPYRIGHT Copyright (C) 2003 Dmitry Fedorov =head1 LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. =head1 DISCLAIMER The author disclaims any responsibility for any mangling of your system etc, that this script may cause. =cut