# updated_line_number.pl # updated_line_number.pl old_file revised_file line_number # # compares old_file to revised_file and will determine what a line number in old_file will be for revised_file # use strict; my ( $old_file, $new_file, $line_number ) = @ARGV; my @new_to_old; my @old_to_new; my $lines_in_new = 0; my $lines_in_old = 0; initialize_arrays(); determine_differences(); print "$old_to_new[$line_number]\n"; sub initialize_arrays{ # Initialize arrays. Size is old + new to give shrink and grow room during calculations. # Just ignore extra when done. open my $new_file_handle, "<", $new_file or die "Unable to open $new_file\n"; $lines_in_new++ while ( <$new_file_handle> ); open my $old_file_handle, "<", $old_file or die "Unable to open $old_file\n"; $lines_in_old++ while ( <$old_file_handle> ); $old_to_new[$_] = 0 for ( 1 .. $lines_in_new + $lines_in_old ); $new_to_old[$_] = $_ for ( 1 .. $lines_in_new + $lines_in_old ); } sub determine_differences{ for my $capture_line ( `diff $old_file $new_file` ) { # Only process lines starting with number. Ignore <, >, or --- lines. if ( $capture_line =~ /^(?:(\d+),)?(\d+)([acd])(?:(\d+),)?(\d+)$/ ) { $3 ne 'd' and $new_to_old[$_] = 0 for ( ( $4 ? $4 : $5 ) .. $5 ); $new_to_old[$_] += ( $4 ? $4 : $5 ) - $5 + $2 - ( $1 : $1 ? $2 ) + ( $3 cmp 'c' ) for ( $5 + 1 .. $lines_in_old + $lines_in_new ); } } # Now get inverse to go from old to new. # There will be complete arrays going old to new and new to old just to get one answer. for my $n ( 0 .. $lines_in_old + $lines_in_new ) { if ( $new_to_old[$n] > 0 ) { $old_to_new[$new_to_old[$n]] = $n; } else { $old_to_new[$n] = 0; # If no match, make line number zero. } } }