情景1
仅当第1列为CR
且第3列与行/值重复时,我才需要进行以下更改。此输入文件可以包含列3中的100个重复行
第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列< / p>
输入文件
a||c
DR||3770022521
DR||3770022521
DR||3770022521
INV||9876543738
输出文件
a||c
DR||3770022521
DR||3770022521aDR
DR||3770022521bDR
INV||9876543738
我尝试了下面的代码,它为方案2提供输出,但无法将序列号附加到column3。我只能后缀a
,这是静态的。
这里需要考虑第1列等于场景1的CR
和场景2的DR
(我无法做到)
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
答案 0 :(得分:2)
我可以提供一种方法来解决第一个场景,您可以使用它来扩展第二个场景。它涉及对文件进行两次解析,但仅限于第二次传递的选定列。如果能够一次性完成,我会兴高采烈地删除答案。
a-z
从sprintf()
生成字母字符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
来扩展第二种方案,并在适用的地方将字符串替换为代码中的变量
答案 1 :(得分:2)
编辑:当@Inian抓住我的手并重新阅读OP给我时,我编辑了脚本以实际支持重复。首先,测试数据要好一些:
a||c
CR||2157237496
CR||2157237497
CR||2157237496
CR||2157237497
INV||2157237496
RNV||3457634589
方案1的awk:
$ 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