Welcome to the monastery, Salwrwr! I'm pretty sure nearly everyone has missed the <code> tags at least once.
A few general tips, and hopefully not too much overlap with the other replies you've already received:
- You're not doing any error checking on file operations. Either employ the usual idiom: open my $fh, '<', $filename or die "Can't open $filename: $!";, or use autodie; to obviate the need to code all the checks yourself.
- You can clean up the print syntax by using join slices: say $newfile join "\t", @line[0,2,3], @values[0..2]; (use 5.010 or later, or use feature 'say' to enable say.
- There's no need to repeatedly split and join @file_data (or even to create @file_data in the first place; do it outside the @position loop and store the result:
my @values = map { join "\t", (split /\t/)[0..2] } <$fh>;
# Later, in your say statement:
say $newfile join "\t", @line[0,2,3], $_ for grep { /^$start\t/ } @val
+ues;