Using substr for this is kinda tricky. If one of the earlier ranges contains 's, and you delete them, that screws up the indexes for later ranges. One solution is to substitute a known-not-present char (I used \x7F) for ' whilst processing the ranges and then remove these from the resultant line.
Update:A modified version to deal with replacing 's with spaces at the end of the field rather than deleting them entirely. Makes use of Fletch's neat trick and Aristotle's enhancement to it, now that is possible.
#! perl -sw use warnings; use strict; open( FILE, '<', shift) or die "Couldn't open $::FILE; $!"; @ARGV = map{ [ split(/-/, $_, 2) ] } @ARGV or die 'usage $0: file c1-c2 [ c1-c2 [ ... ] ] >modified_file'; while (my $line = <FILE>) { for ( @ARGV ) { next if $_->[0] > length $line; $_->[1] = length $line if $_->[1] > length $line; local *_ = \substr($line, $_->[0], $_->[1]-$_->[0] + 1); tr[a-zA-Z0-9\n\|\-'][ ]c; $_ .= ' ' x tr['][]d; } print $line; } close FILE;
Original version
#! perl -sw use warnings; use strict; open( FILE, '<', shift) or die "Couldn't open $::FILE; $!"; @ARGV = map{ [ split(/-/, $_, 2) ] } @ARGV or die 'usage $0: file c1-c2 [ c1-c2 [ ... ] ] >modified_file'; while (my $line = <FILE>) { for ( @ARGV ) { next if $_->[0] > length $line; $_->[1] = length $line if $_->[1] > length $line; substr($line, $_->[0], $_->[1]-$_->[0] + 1) =~ s[(^.*$)] { local $a = $1; $a =~ tr[a-zA-Z0-9\n\|\-'][ ]c; $a =~ tr['][\x7f]; $a; }e; $line =~ tr[\x7F][]d; } print $line; } close FILE;
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.
In reply to Re: Cleaning Data Between Specified Columns
by BrowserUk
in thread Cleaning Data Between Specified Columns
by enoch
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |