$ cat -vet working.txt H$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Iswap1$ ...$ source for^Ireplace1$ ...$ ^LH$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Iswap2$ ...$ source for^Ireplace2$ ...$ ^LH$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Iswap3$ ...$ source for^Ireplace3$ ...$ #### #!/usr/bin/env perl use strict; use warnings; use autodie; use constant { CHANGE_LINE => 4, SOURCE_LINE => 6, PAGE_SEP => "\n\fH\n", }; use File::Copy 'copy'; my $work_file = 'working.txt'; my $bu_file = 'working.txt.bu'; copy($work_file, $bu_file) or die "Can't 'copy($work_file, $bu_file)': $!"; { open my $in_fh, '<', $bu_file; open my $out_fh, '>', $work_file; local $/ = PAGE_SEP; while (<$in_fh>) { chomp; my @lines = split /\n/; my ($change_line, $source_line) = (CHANGE_LINE, SOURCE_LINE); ++$change_line, ++$source_line if $. == 1; my ($replace) = $lines[$source_line] =~ /(\S+)$/; $lines[$change_line] =~ s/\S+$/$replace/; print $out_fh join("\n", @lines), (eof($in_fh) ? "\n" : PAGE_SEP); } } #### $ cat -vet working.txt H$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Ireplace1$ ...$ source for^Ireplace1$ ...$ ^LH$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Ireplace2$ ...$ source for^Ireplace2$ ...$ ^LH$ after 1 space$ after 2 spaces$ no leading spaces$ text^I^Ifollowed by 2 tabs$ target for^Ireplace3$ ...$ source for^Ireplace3$ ...$ #### $ perl -E 'my $x = "|\t|"; say $x; say length $x;' | | 3 #### $ perl -E ' my $x = "PROMPT\t\tTO CHANGE"; my $len = length $x; my $from_index = rindex($x, "\t") + 1; my $from_pos = $from_index + 1; say $x; say "$from_pos through $len"; say substr $x, $from_index, $len - $from_index; say substr $x, $from_index; ' PROMPT TO CHANGE 9 through 17 TO CHANGE TO CHANGE