I have a file with one line like:
onspaces -a dataidx -p /dev/itest17/idx_dataidx20 -o 0 -s 2097150
I need to increment the number by one so the output would be:
onspaces -a dataidx -p /dev/itest17/idx_dataidx21 -o 0 -s 2097150
The could also have a line such as:
onspaces -a dataidx -p /dev/itest17/foobar01 -o 0 -s 2097150
which would result in
onspaces -a dataidx -p /dev/itest17/foobar02 -o 0 -s 2097150
I have tried
`perl -i -pe 'if ($. == 1)
{($n) = ($m) = /([09] )$/;
$m;s/$n/$m/g;
} else {s/$n(?= )/$m/;}' in_file`
which was a solution to a previous question that I asked that was solved, but this one seems to be a bit different. Thanks in advance!
Note: I'm using an ancient version of Perl, 5.8.3.
CodePudding user response:
Similarly to the solution I provided to you previously:
perl -i~ -pe 's/([0-9] )(?= -o)/$x = $1; $x/e' file
I.e. find a sequence of digits [0-9]
followed by a space and -o (?= -o)
, replace the digits by the incremented number. The /e
interprets the replacement as a code to run, using
ensures the leading zeroes are kept.
CodePudding user response:
The only really "moving part" here is about finding the place in the line where that number is. It appears that it is the end of a path following -p
? Then let's match, and change, that
perl -pe's{\-p\s /\S [^0-9]\K([0-9] )\b}{ 1 $1 }e' file
Prints as expected on the provided input. To change the file in-place add the -i
, as in the question, after thorough testing.
This makes assumptions, since the quetion isn't very precise (for example, that a path has no spaces). It can be tweaked -- and perhaps simplified -- depending on the exact requirements. If the question is updated with more details I can update (or offer alternatives).
A brief explanation and alternatives
The /e
modifier makes the replacement side be evaluated as code so we can do our math there, and what that code returns is then used as the replacement. The \K
nicely "drops" everything matched up to that point, so the replcement won't touch previous matches.
However, comments clarify that this is perl v5.8.3 (twenty years old). Then \K
may not work, and without it we have to capture everything preceding the number to change, and put it back
perl -pe's{(\-p\s /\S [^0-9])([0-9] )\b}{ $1.(1 $2) }e' file
A number can be expected to lose the leading zero(s), if there are any, with the above code (even thoughfor a string like in the question it keeps it). If that is a problem we can assign the $1
to a variable and increment that, when leading zeros are kept. A nice trick from jhnc
in a comment keeps it compact, too
perl -pe's{(\-p\s /\S [^0-9])([0-9] )\b}{ $1.( ($_=$2)) }e' file
Or, if that's too much trickery for someone's test just add a variable
perl -pe's{(\-p\s /\S [^0-9])([0-9] )\b}{ $n = $2; $1.( $n) }e' file
(with strict
in place that'd need to be my $n = $2
)