# construct the template in a more self-documenting way. # this is a list of name => width values. you can add # more info here if you like; just adjust the loops # that pull information out of it. having all this # information in one place means that you only have to # change one place... my @INPUT_COLUMN_INFO = ( unknown1 => { width => 12 }, unknown2 => { width => 4 }, source => { width => 20 }, dest => { width => 20 }, ... ); # you can also use this structure to do clever things # such as building a hash out of each input line to # extract values by name instead of by numeric index. # ================================================= # derived constants my @INPUT_NAMES; # names in original order my $INPUT_TEMPLATE; # build up an 'unpack' template my %INPUT_POS; # map from name to index for ( my $i = 0; $i < @INPUT_COLUMN_INFO; $i += 2 ) { my ( $name, $info ) = @INPUT_COLUMN_INFO[$i, $i+1]; push @INPUT_NAMES, $name; $INPUT_TEMPLATE .= "A" . $info->{width}; $INPUT_POS{$name} = @INPUT_NAMES-1; } # ================================================= # use during processing while (<>) { # construct hash using slice my %input; @input{@INPUT_NAMES} = unpack $INPUT_TEMPLATE, $_; # now access info from the hash my $src = $input{source}; my $dest = $input{dest}; # ... }