falcon198198 said:
Can someone help me understand a part of this script. Personally I
would not have written the script this way but it is someone elses
system and I need to understand the code. This script is called in a
printing system and is renaming the 2 characters in the file name.
The line I am trying to understand is the translation part. (Again I
did not write this so please take it easy on me )
# These are the translations
$trans{"MO"} = "ST";
$trans{"TU"} = "ST";
$trans{"WE"} = "ST";
$trans{"TH"} = "ST";
$trans{"FR"} = "ST";
$trans{"SA"} = "ST";
$trans{"SU"} = "ST";
$trans{"AD"} = "ST";
$trans{"PP"} = "ST";
$trans{"RL"} = "ST";
$trans{"00"} = "ST";
# Save the input filename
$orig = $_ = shift;
# Run the translation
if (/(#PP)?.{7}(..).*/ig and exists($trans{$2})) {
s/(#PP)?(.{7})(..)(.*)/$1$2$trans{$3}$4/ig;
}
These three lines above appear to do the same thing as this
shown in alternation format, if that is easier to understand..
s/^(#[pP][pP])?(.{7})(MO|TU|WE|TH|FR|SA|SU|AD|PP|RL|00)/$1ST/;
If filename contains any of this set of characters starting at position 8,
or at position 11, only if the first 3 characters are #PP (any case)
then change these matched trans characters to "ST".
The g (global) switch is a little misleading, since the (.*) will use up
the rest of the line, so there can be only one s/// at most,
so I left it off.
The i (insensitive to case) switch is a little misleading,
since the test "and exists( $hash{ key })" will only pass if the
key exists, and the keys "MO", "TU" etc are all uppercase,
so I left it off. It does affect the PP, so I put in [pP][pP] to match that.
I almost wrote:
The (#PP)? is a little misleading, since it is optional,
so there are no such lines that will be matched or not-matched
based only on the (#PP?) criteria, so it might as well not exist.
But after testing, I see there is some interaction between regexp
and the exists. The regexp matches at the first opportunity,
so there is an implied ^ to bind to the front of the line.
I couldn't find any testcases where the trans characters
were matched other than at positions 8 or 11.
If the name does not match the pattern,
then $orig is still same as $_
# Move the file, even onto itself, if it was not renamed.
Possibly moving the file ontop of itself,
if it did not match the pattern.
The posting guidelines suggest showing a short but complete script,
but don't give any examples. Here is an example of a test script
to tickle this transformation so you can see what it might match
or not match, and explore for yourself.
use warnings; use strict; no warnings "uninitialized";
my %trans= qw(
MO ST TU ST WE ST TH ST FR ST SA ST SU ST AD ST PP ST RL ST 00 ST);
while(<DATA>){
chomp;
my $orig = $_ ; # = shift;
if ( /(#PP)?.{7}(..).*/ig and exists($trans{$2})) {
s/(#PP)?(.{7})(..)(.*)/$1$2$trans{$3}$4/ig;
}
printf "%-25s%-25s %s\n",$orig,$_,($orig eq $_ ? 'No':'Yes');
}
exit;
__DATA__
_NO___SUCHFILE.txt
1234567MO
1234567TU
1234567we
#PP1234567PP
#PP12345678PP.txt
PPPPPPPPPPP
123#PP1234567PP.txt
#pp1234567PP.txt
#PP#ppppppADSU
Output:
_NO____SUCHFILE.txt _NO___STCHFILE.txt Yes
1234567MO 1234567ST Yes
1234567TU 1234567ST Yes
1234567we 1234567we No
#PP1234567PP #PP1234567ST Yes
#PP12345678PP.txt #PP12345678PP.txt No
PPPPPPPPPPP PPPPPPPSTPP Yes
123#PP1234567PP.txt 123#PP1234567PP.txt No
#pp1234567PP.txt #pp1234567ST.txt Yes
#PP#ppppppADSU #PP#ppppppSTSU Yes
If the no warnings "uninitalized";
is commented out, then this warning is printed
for every matching line that has no #pp leader, for some reason.
Use of uninitialized value in concatenation (.) or string at trans1.pl line 8, <DATA> line 7.