G'day onemojofilter,

Your data contains four types of whitespace (assuming your alignment uses tabs). These are difficult to differentiate on a webpage. I've used `cat -vet` which shows: a tab as ^I; a form feed as ^L; a newline as $; and, a space as itself.

I created the following test data (working.txt) which has examples of the different types of whitespace. I added an additional page so you now have a "^LH" following both an "H" and a "^LH". I removed much of the original data and replaced the rest with text intended to explain each line. I believe this is still representative of what you originally showed.

$ 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$ ...$

I then ran this code:

#!/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); } }

Here's the result:

$ 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$ ...$

Note that all of the original whitespace is retained unaltered. I do recommend you make a backup; doing this within the code is easiest and won't be forgotten.

Your initial text positions were incorrect. "25 through 35" covers 11 characters, but "20221103" is only 8 characters. Also, I made the starting position 23 not 25, and that assumes that all of the preceding whitespace was actually spaces; if some, or all, were tabs, that would be a different number. Tabs are just a single character:

$ perl -E 'my $x = "|\t|"; say $x; say length $x;' | | 3

If the situation is more complex than suggested in your OP, let Perl do the counting for you. Bear in mind that your character positions may start at 1 (1st char. is at pos. 1) but Perl will count from zero. I've no idea what you might need, but this should give you some hints:

$ 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

— Ken


In reply to Re: Changing string in specific line/position in a file by kcott
in thread Changing string in specific line/position in a file by onemojofilter

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.