OK, let's start with a slightly longer
awk:
Code:
awk -F'[^0-9]+' '{
s = sprintf("%0*d", length($NF), $NF+1);
sub($NF"$",s,$0);
print $0
}'
1/ I launch
awk with the
-F switch, which sets the
field separator to the
regex [^0-9]+, so that the last field will be the number at the end of the string.
2/ the last argument is the actual
awk program. An
awk program is basically a chain of rules in the form
. For each record read,
awk goes through all the rules, and, if the
CONDITION is true, executes the corresponding
CODE
My program has only one rule (a rule with no
CONDITION specified is always executed).
3/
Code:
s = sprintf("%0*d", length($NF), $NF+1);
is pretty self-explanatory.
$NF is the last field of the current record.
4/
is a
regex substitution, where
$NF"$", the number with an "end of string" anchor is the pattern,
s is the replacement string and
$0 (the entire record read) is the target string.
5/
prints the current record to
stdout.
Now there's a few things to note:
i) I cannot assign directly to
$NF, because that forces
$0 to be reassembled using the curent
OFS (output field separator), which means losing all non-numeric characters.
ii) I can get rid of the extra assignment to
s and combine the first two commands together. Also, since
$0 is the default target string for
sub, that argument can be omitted:
Code:
awk -F'[^0-9]+' '{
sub($NF"$",sprintf("%0*d", length($NF), $NF+1));
print $0
}'
iii) The CONDITION may be practically any expression that can be converted to a boolean value.
iv) The
sub function returns number of replacements done. In this case, because
$NF is always a subset of
$0, it is the last field, and every string has exactly one end, it will always return 1 (a
true value).
v) Using iii) and iv) we can put the
sub statement out of the braces and use it as a
CONDITION:
Code:
awk -F'[^0-9]+' 'sub($NF"$",sprintf("%0*d", length($NF), $NF+1)) { print $0 }'
vi) because
{ print $0; } is the default action, it can be omitted.
Code:
awk -F'[^0-9]+' 'sub($NF"$",sprintf("%0*d",length($NF),$NF+1))'
Actually, the '+' in the field separator is not required and may be left out as well.
awk will then split the filename into more fields, but in the end, the result will be the same.