计算 _ 的最大数量,如果缺少分号,则添加额外的分号

count the max number of _ and add additional semi-colon if some are missing

我有几个文件包含如下字段

xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;deme_Fort_Email_am;04/02/2015;Deme_Fort_Postal
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;deme_faible_Email_am;18/02/2015;deme_Faible_Email_Relance_am
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;equi_Fort_Email_am;23/02/2015;trav_Fort_Email_am
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav_Faible_Email_pm;18/02/2015;trav_Faible_Email_Relance_pm
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav_Fort_Email_am;12/02/2015;Trav_Fort_Postal
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;voya_Faible_Email_am;29/01/2015;voya_Faible_Email_Relance_am

目标是

xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;deme;Fort;Email;am;04/02/2015;Deme;Fort;Postal;;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxxdeme;faible;Email;am;18/02/2015;deme;Faible;Email;Relance;am
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;equi;Fort;Email;am;23/02/2015;trav;Fort;Email;am;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav;Faible;Email;pm;18/02/2015;trav;Faible;Email;Relance;pm
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav;Fort;Email;am;12/02/2015;Trav;Fort;Postal;;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;voya;Faible;Email;am;29/01/2015;voya;Faible;Email;Relance;am

我正在计算任何行的第 7 个字段之后的下划线最大值。然后,我将其更改为分号,并根据在所有行中找到的最大下划线数添加额外的分号。

我考虑过为此使用 awk,但我只会使用下面的命令行更改第一个字段之后的所有内容。我的目的也是添加额外的分号

awk 'BEGIN{FS=OFS=";"} {for (i=7;i<=NF;i++) gsub(/_/,";", $i) } 1' file

谢谢。

糟糕的方式

awk -F';' -vOFS=';' '{y=0;for(i=8;i<=NF;i++)y+=gsub(/_/,";",$i)
                     x=x<y?y:x;NF=NF+(x-y)}NR!=FNR' file{,}

输出

xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;deme;Fort;Email;am;04/02/2015;Deme;Fort;Postal;;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;deme;faible;Email;am;18/02/2015;deme;Faible;Email;Relance;am
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;equi;Fort;Email;am;23/02/2015;trav;Fort;Email;am;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav;Faible;Email;pm;18/02/2015;trav;Faible;Email;Relance;pm
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;trav;Fort;Email;am;12/02/2015;Trav;Fort;Postal;;
xxx;x_x_x;xxx;xxx;x_x_x;xxx;xxx;voya;Faible;Email;am;29/01/2015;voya;Faible;Email;Relance;am

解释

awk -F';' -vOFS=';'

这会将字段分隔符和输出字段分隔符设置为 ;

y=0;

每行将 y 初始化为 0。

for(i=8;i<=NF;i++)y+=gsub(/_/,";",$i)

对于从字段 8 到行中字段数 (NF) 的每个字段。将 _ 替换为 ;。将 y 增加替换次数。

x=x<y?y:x

检查 x 是否小于 y,如果将 x 设置为 y,否则保持不变。

NF=NF+(x-y)

设置字段数为当前字段数+x与y之差

NR!=FNR

这意味着如果总记录数不等于文件记录数那么print.Effectively意味着打印任何不是第一个文件的东西。

file{,}

扩展为 file file 因此文件被读取两次。


资源

https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html