使Linux中的文件中的重复字符串唯一

使Linux中的文件中的重复字符串唯一

我有一个像这样的文件 prueba.ldif:

dn: EpsStaInfId=EpsStaInf,serv=EPS,mscId=0015f5e3d05d4d52b0cb85db69474db3,ou=multiSCs,dc=three
structuralObjectClass: EpsStaticInf
objectClass: EpsStaticInf
entryDS: 1
nodeId: 21
createTimestamp: 20220303153032Z
modifyTimestamp: 20220303153032Z
EpsStaInfId: EpsStaInf
EpsProfileId: 10
EpsOdb: 0
EpsRoamAllow: TRUE
CDC: 1
EpsIndDefContextId: 1
EpsIndAmbrMaxUl: 320000000
EpsIndAmbrMaxDl: 1024000000
EpsRoamRestrict: TRUE
EpsTenantId: 1
EpsIndContextId: 1
EpsIndContextId: 2

dn: EpsStaInfId=EpsStaInf,serv=EPS,mscId=0040fb1140104f9fbc4be38be3db5965,ou=multiSCs,dc=three
structuralObjectClass: EpsStaticInf
objectClass: EpsStaticInf
entryDS: 1
nodeId: 21
createTimestamp: 20220301120221Z
modifyTimestamp: 20220301120221Z
EpsStaInfId: EpsStaInf
EpsProfileId: 10
EpsOdb: 0
EpsRoamAllow: TRUE
CDC: 1
EpsIndDefContextId: 1
EpsIndAmbrMaxUl: 320000000
EpsIndAmbrMaxDl: 1024000000
EpsRoamRestrict: TRUE
EpsTenantId: 1
EpsIndContextId: 1
EpsIndContextId: 5
EpsIndContextId: 15

我想为每个 dn 制作唯一的 EpsIndContextId,在末尾添加一个数字,得到如下文件:

dn: EpsStaInfId=EpsStaInf,serv=EPS,mscId=0015f5e3d05d4d52b0cb85db69474db3,ou=multiSCs,dc=three
structuralObjectClass: EpsStaticInf
objectClass: EpsStaticInf
entryDS: 1
nodeId: 21
createTimestamp: 20220303153032Z
modifyTimestamp: 20220303153032Z
EpsStaInfId: EpsStaInf
EpsProfileId: 10
EpsOdb: 0
EpsRoamAllow: TRUE
CDC: 1
EpsIndDefContextId: 1
EpsIndAmbrMaxUl: 320000000
EpsIndAmbrMaxDl: 1024000000
EpsRoamRestrict: TRUE
EpsTenantId: 1
EpsIndContextId1: 1
EpsIndContextId2: 2

dn: EpsStaInfId=EpsStaInf,serv=EPS,mscId=0040fb1140104f9fbc4be38be3db5965,ou=multiSCs,dc=three
structuralObjectClass: EpsStaticInf
objectClass: EpsStaticInf
entryDS: 1
nodeId: 21
createTimestamp: 20220301120221Z
modifyTimestamp: 20220301120221Z
EpsStaInfId: EpsStaInf
EpsProfileId: 10
EpsOdb: 0
EpsRoamAllow: TRUE
CDC: 1
EpsIndDefContextId: 1
EpsIndAmbrMaxUl: 320000000
EpsIndAmbrMaxDl: 1024000000
EpsRoamRestrict: TRUE
EpsTenantId: 1
EpsIndContextId1: 1
EpsIndContextId2: 5
EpsIndContextId3: 15

我怎样才能做到这一点?

答案1

perl

perl -pe '$i = 0 if /^dn:/; s/^EpsIndContextId\K/++$i/e' < prueba.ldif

或者编辑文件in-place:

perl -i -pe '$i = 0 if /^dn:/; s/^EpsIndContextId\K/++$i/e' prueba.ldif

dn:上面,每当遇到以 开头的行时,我们都会重置计数器。您可以改为if /^dn:/搜索if /^$/空行或unless /\S/搜索空行(仅由空格字符组成的行),或者如@glennjackman建议的那样,使用段落模式,其中-00记录而不是行,由以下序列分隔一个或多个空行(2 个或多个换行符),并使用m替换中的标志来^匹配主题(段落)中每一行的开头,而不是仅在主题的开头和标志g来替换每个记录中出现的情况:

perl -00 -pe '$i = 0; s/^EpsIndContextId\K/++$i/emg' < prueba.ldif

答案2

这是一个sed解决方案:

sed -E 's/(^EpsIndContextId)(:) (.*$)/\1\3\2 \3/' prueba.ldif

答案3

POSIX awk

awk '/^dn: /{c=0} /^EpsIndContextId/{sub(/^EpsIndContextId/, "&"++c)} 1' test

重置计数器 ( c) 和每个部分 ( ) 的开头dn,因此每次它找到一个计数器时,EpsIndContextId它都会增加计数器并将其添加到此部分。

或者作为,@埃德·莫顿建议:

awk '/^dn: /{c=0} sub(/^EpsIndContextId/, "&"c+1){c++} 1' test

以避免使用相同的正则表达式两次。

相关内容