If your input contains only strings of "v" followed by digits, AND you're OK with space-separated output, this perl script can do what you want:
$ echo 'v100 v201 v102 v300 v301 v500 v999 v301' |
perl -lne '
@line = ();
#my $i=0;
#my %seen=();
while (/(v\d+)/g) {
$seen{$1} = "v" . ++$i unless ($seen{$1});
push @line, $seen{$1}
};
print join(" ",@line);'
v1 v2 v3 v4 v5 v6 v7 v5
perl's -n
option iterates over each line of input (similar to a sed -n
script), and -l
automatically chomps newlines from the ends of input lines and adds them back to print statements.
The while (/(v\d+)/g)
loop iterates over (and captures into $1
) all of the strings matching v\d+
in each input line. If that match hasn't been seen before, increment the counter and add it to the %seen hash. Then push
(i.e. add it to the end) of an array called @line
. After the while loop ends (i.e. after that input line has been processed), print the @line array with a space character between each element.
The @line array is reset to empty for each input line. If you also want the numbering ($i
) and the %seen
hash to be reset for every input line, uncomment the two lines before the while(...)
line:
my $i=0;
my %seen=();
awk
orsed
have not any more to do withbash
thanperl
.perl
madesed
andawk
obsolete in the mid 80s.awk
andsed
are as much external languages to that ofbash
thanperl
.perl
but not onpython
. Still,sed
andawk
feel much morebash
thanperl
does. Yes, that's subjective :)