将零添加到列表中

时间:2018-04-11 03:10:13

标签: regex perl awk

我有以下输入文件:

a,10,12,13
b,20,22
c,30
d,33

并且想在每行包含三个数字之前附加零,所以这应该是输出:

a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

sed我可以使用这两个命令:

sed 's/\([a-z],[0-9]\+$\)/\1,0,0/g'
sed 's/\([a-z],[0-9]\+,[0-9]\+$\)/\1,0/g'

我的正则表达式知识仅限于sed,我想知道如何使用awkperl实现这一目标。

7 个答案:

答案 0 :(得分:5)

作为Perl one-liner

perl -pe 's/$/,0/ until tr/,// >= 3' myfile

输出

a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

答案 1 :(得分:4)

awk超级简单。

$ awk -F, '{for(;NF<4;$(NF+1)=0);} 1' OFS=, i.csv

这使用for循环,其条件是您的字段计数目标,其操作添加另一个字段。这适用于BSD awk和GNU awk,我还没有在mawk或其他awk中测试过。

然而,在sed中,解决方案看起来有点复杂。

$ sed -e ':start' -e '/,.*,.*,/b end' -e 's/$/,0/' -e 'b start' -e ':end' i.csv

或更紧凑:

$ sed -e ':start
  /,.*,.*,/b end
  s/$/,0/
  b start
  :end' i.csv

此处的策略是通过查找三个字段分隔符来测试四个字段,然后逐步执行添加,0的循环,直到我们通过该测试,此时我们b end(分支到要退出的:end标签)。然后打印该行,因为这是默认操作。

这是在BSD sed中测试的,但在GNU sed中应该同样兼容(也许更加紧凑)。

答案 2 :(得分:4)

$ awk 'BEGIN{FS=OFS=","} {for (i=2;i<=4;i++) $i+=0} 1' file
a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

答案 3 :(得分:4)

使用perl

$ perl -F, -lane 'print join ",", @F, (0)x(3-$#F)' ip.txt
a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

$ perl -F, -lane 'print join ",", @F, ("NA")x(3-$#F)' ip.txt
a,10,12,13
b,20,22,NA
c,30,NA,NA
d,33,NA,NA
  • -F,输入字段分隔符为,,结果可从@F数组访问
  • (0)x(3-$#F)添加缺失的零。 $#F给出了最后一个元素的索引,例如第二行的2 - 所以添加了3-2个零
    • ("NA")x(3-$#F)使用NA代替0作为填充元素
  • join ","使用,作为分隔符来连接数组元素


灵感来自Borodin的回答

$ perl -pe 's|$|",0" x (3 - tr/,//)|e' ip.txt 
a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0
  • e修饰符允许在替换部分中使用Perl代码
  • tr/,//会在输入行中提供,的数量
  • x将按(3 - tr/,//)
  • 重复给定的字符串

答案 4 :(得分:3)

关注awk也可能有所帮助。

awk -F, 'NF<4{i="";while(i<(4-NF)){val=val?val OFS "0":",0";i++}}{print $0 val;val=""}' OFS=,  Input_file

现在也添加非单线形式的解决方案。

awk -F, '
NF<4{
  i="";
  while(i<(4-NF)){
    val=val?val OFS "0":",0";
    i++}
}
{
  print $0 val;
  val=""
}' OFS=,  Input_file

答案 5 :(得分:2)

在awk中:

$ awk 'BEGIN{FS=OFS=",";nf=4}{for(i=(NF+1);i<=nf;i++)$i=0}1' file
a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

说明:

$ awk '
BEGIN {
    FS=OFS=","               # separators
    nf=4                     # desired field count
}
{
    for(i=(NF+1);i<=nf;i++)  # da loop to create new fields
        $i=0                 # set new fields to 0 
}1' file                     # output

答案 6 :(得分:0)

awk 'BEGIN{FS=OFS=","}$3==""{$3="0"}$4==""{$4="0"}1' file

a,10,12,13
b,20,22,0
c,30,0,0
d,33,0,0

首先它表示将字段分隔符保留在输出中,然后用$ 3填充空字段,$ 4用零填充。