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

时间:2015-03-09 11:18:14

标签: bash awk

我有几个文件,其中包含以下字段

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

感谢。

1 个答案:

答案 0 :(得分:2)

awk方式

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,则保持不变{/ 1}}。

NF=NF+(x-y)

将字段数设置为当前字段数+ x和y之间的差值。

NR!=FNR

这意味着如果总记录数不等于文件记录号,则打印。有效地表示打印不是第一个文件的任何内容。

file{,}

扩展为file file,以便读取文件两次。


资源

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