Присваивать порядковый номер элементам, пока заданные элементы не будут найдены уникальными, а затем перейти к следующему номеру в последовательности

Присваивать порядковый номер элементам, пока элементы не будут найдены уникальными, а затем перейти к следующему номеру в последовательности

например, порядковый номер начинается с GST-17/18/SO-004072

Предметы

773
773
289
289
912
912
912
912
644
644
644

для выделения первого числа в последовательности будет как показано ниже

773 GST-17/18/SO-004072
773 GST-17/18/SO-004072

и перейти к следующему уникальному набору предметов и так далее

289 GST-17/18/SO-004073
289 GST-17/18/SO-004073

конечный желаемый результат будет

773 GST-17/18/SO-004072
773 GST-17/18/SO-004072
289 GST-17/18/SO-004073
289 GST-17/18/SO-004073
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
644 GST-17/18/SO-004075
644 GST-17/18/SO-004075
644 GST-17/18/SO-004075

3 ответа

Решение

Вы можете использовать awk:

awk -v s='GST-17/18/SO-004072' 'BEGIN{k=s; sub(/^.+-/, "", k)}
p && p != $1{sub(/-[^-]+$/, sprintf("-%06d", ++k), s)}
{print $1, s; p=$1}' file

773 GST-17/18/SO-004072
773 GST-17/18/SO-004072
289 GST-17/18/SO-004073
289 GST-17/18/SO-004073
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
912 GST-17/18/SO-004074
644 GST-17/18/SO-004075
644 GST-17/18/SO-004075
644 GST-17/18/SO-004075

Учить awk:

Следующий awk может также помочь вам в том же.

awk -v s1="-" -v num="GST-17/18/SO-004072" 'BEGIN{split(num, array,"-")} prev!=$0 && prev{array[3]++;val=array[1] s1 array[2] s1 sprintf("%06d",array[3])} {val=val?val:num;print $0,val;prev=$1}'  Input_file

Здесь также можно добавить не одну линейную форму решения.

awk -v s1="-" -v num="GST-17/18/SO-004072" '
BEGIN{
  split(num, array,"-")}
prev!=$0 && prev{
  array[3]++;
  val=array[1] s1 array[2] s1 sprintf("%06d",array[3])}
{
  val=val?val:num;
  print $0,val;
  prev=$1}
'   Input_file

Перл однострочный:

perl -lpe '$_=$s=sprintf q{%d GST-17/18/SO-%06d}, $_, ($t//=4071)+=($s!=$_)' in.txt

что эквивалентно (кроме проверок безопасности) следующей длинной версии:

use strict;
use warnings;

my ($t,$s)=(4072-1,);
while (<>) {
  chomp;
  no warnings qw(numeric uninitialized);
  if ($s!=$_) {
    $t++;
  }
  $s=sprintf "%d GST-17/18/SO-%06d\n", $_, $t;
  print $s;
}
Другие вопросы по тегам