Скрипт Awk для добавления суффикса к столбцу, когда столбец имеет повторяющиеся значения - PullRequest
0 голосов
/ 09 мая 2018

Сценарий 1

Мне нужно вносить изменения ниже только в том случае, если столбец 1 равен CR, а в столбце 3 есть дубликаты строк / значений. Этот входной файл может содержать 100 дублированных строк столбца 3

.

Значение в столбце 3 должно быть суффиксом с последовательностью, начинающейся с a, за которой следует CR.
если мы добавили суффикс до a к z с CR как (aCR, bCR, cCR до zCR), то следующий суффикс будет aaCR, abCR, acCR и так далее для столбца 3

Входной файл

a||c
CR||2157237496
CR||2157237496
CR||2157237496
INV||2157237496
RNV||3457634589

Выходной файл

a||c
CR||2157237496aCR
CR||2157237496bCR
CR||2157237496cCR
INV||2157237496
RNV||3457634589

Сценарий 2

Нужно сделать это в отдельном коде. Ниже для другого файла. Мне нужно внести изменения ниже только в том случае, если столбец 1 является DR, а в столбце 3 есть дубликаты строк / значений. Значение в столбце 3 должно быть суффиксом с последовательностью, начинающейся с a, за исключением первого документа, за которым следует DR.

Если мы добавили суффикс до a к z с DR как (aDR, bDR, cDR до zDR), то следующий суффикс будет aaDR, abDR, acDR и так далее для столбца 3

Входной файл

a||c
DR||3770022521
DR||3770022521
DR||3770022521
INV||9876543738

Выходной файл

a||c
DR||3770022521
DR||3770022521aDR
DR||3770022521bDR
INV||9876543738

Я попробовал приведенный ниже код, он дает мне вывод для сценария 2, но не может добавить порядковый номер в column3. Я могу суффикс только a, который является статическим. Здесь необходимо учитывать столбец 1 равным CR для сценария 1 и DR для сценария 2 (что я не могу сделать)

awk -F"|" -v OFS="|" '{if(++a[$3]>1)$3=$3"a"}1' d1.txt

Вывод кода:

a||c
CR||2157237496
CR||2157237496a
CR||2157237496a
INV||2157237496a
RNV||3457634589

Мне нужно реализовать сценарии 1 и 2 отдельно

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Редактировать : Когда @Inian держал меня за руку и перечитывал мне ОП, я отредактировал скрипт, чтобы фактически поддерживать дубликаты. Во-первых, немного лучшие тестовые данные:

a||c
CR||2157237496
CR||2157237497
CR||2157237496
CR||2157237497
INV||2157237496
RNV||3457634589

awk для сценария 1:

$ awk '
BEGIN {
    FS=OFS="|"                       # field delimiters
    ab="zabcdefghijklmnopqrstuvwxy"  # mod safe alphabet
    d=26                             # size of alphabet
}
function i2ab(n,    b) {             # b is local var
    while(n>=1) {
        p=n%d                        # this is the letter position
        n=n/d                        # n for the next round
        n-=(n==int(n))               # fix for n%d==0 else 26 -> az, not z
        b=substr(ab,p+1,1) b         # prepend the next letter to buffer
    }
    return b                         # return buffer
} 
$1=="CR" {                           # for DR change CR to DR and ++a[$3] to a[$3]++ below
    $3=$3 i2ab(++a[$3]) $1           # increment c and map it to a string
}1' file                             # output
a||c
CR||2157237496aCR
CR||2157237497aCR
CR||2157237496bCR
CR||2157237497bCR
INV||2157237496
RNV||3457634589

См. Комментарии для изменения его для работы со сценарием 2.

Функция i2ab также обеспечивает комбинации букв после 26:

$ awk '
BEGIN {
    ab="zabcdefghijklmnopqrstuvwxy"
    d=26
    print i2ab(27)                   # I AM HERE 26 -> z, 27 ->aa
}                                           
function i2ab(n,    b) {                    #
    while(n>=1) {                           #
        p=n%d                               #
        n=n/d                               #
        n-=(n==int(n))                      #
        b=substr(ab,p+1,1) b              #####
    }                                      ###
    return b                                #
}'
aa                                    # I DID THIS
0 голосов
/ 09 мая 2018

Я могу предоставить способ решения первого сценария, с помощью которого вы также можете расширить второй сценарий. Он включает в себя двухкратный разбор файла, но только для выбранных столбцов на втором проходе. Я с радостью удалю ответ, если это можно сделать за один проход.

Steps

  • Создайте функцию для генерации буквенных символов из a-z по мере необходимости, используя sprintf() с кодами ASCII
  • На первом проходе создайте хэш-карту для значений, содержащихся в третьем столбце, для значений в первом столбце как CR
  • На втором проходе для этих столбцов снова измените $3, чтобы сгенерировать нужный вам шаблон.

Сценарий должен быть примерно таким, как показано ниже. Назовите это как script.awk

#!/usr/bin/env awk


function generateAlphabets() {
    idx = 0
    for(i=97;i<123;i++ ) {
        letters[idx++]=sprintf("%c",i)
    }
}

BEGIN {
    generateAlphabets()
    FS=OFS="|"
    counter=0
}

$1 == "CR" {
    map[$1""$3]
}

FNR == NR { next }

($1""$3 in map) {
    $3 = $3""letters[counter++]"CR"
}1

Запустите приведенный ниже скрипт как

awk -f script.awk file file

Вы можете расширить это для второго сценария, поместив переменную awk для передачи CR или DR и замените строку переменной в коде, где это применимо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...