Regex 使用awk/perl检查小数点,如果没有小数点,则将其添加到末尾

Regex 使用awk/perl检查小数点,如果没有小数点,则将其添加到末尾,regex,perl,shell,awk,Regex,Perl,Shell,Awk,我有test.dat文件,其值如下所示: 20150202,abc,,,,3625.300000,,,,,-5,,,,,,,,,,,,,,,,,,,,,, 20150202,def,,,,32.585,,,,,0,,,,,,,,,,,,,,,,,,,,,, 20150202,xyz,,,,12,,,,,0.004167,,,,,,,,,,,,,,,,,,,,,, Use of uninitialized value in split at test.pl line 11

我有test.dat文件,其值如下所示:

    20150202,abc,,,,3625.300000,,,,,-5,,,,,,,,,,,,,,,,,,,,,,
    20150202,def,,,,32.585,,,,,0,,,,,,,,,,,,,,,,,,,,,,
    20150202,xyz,,,,12,,,,,0.004167,,,,,,,,,,,,,,,,,,,,,,
Use of uninitialized value in split at test.pl line 11, <$fh> line 1.
Use of uninitialized value in pattern match (m//) at test.pl line 13, <$fh> line 1.
Use of uninitialized value in pattern match (m//) at test.pl line 13, <$fh> line 1.
Use of uninitialized value in join or string at test.pl line 15, <$fh> line 1.
....
我的预期输出如下所示:

   20150202,abc,,,,3625.300000,,,,,-5.,,,,,,,,,,,,,,,,,,,,,,
                                     ^. added here
   20150202,def,,,,32.585,,,,,0.,,,,,,,,,,,,,,,,,,,,,,
                               ^. added here
   20150202,xyz,,,,12.,,,,,0.004167,,,,,,,,,,,,,,,,,,,,,,
                     ^. added here
因此,如果第6列和第11列中没有小数点,那么我们应该在文件末尾添加“.”

我尝试了下面的代码,但在拆分过程中抛出了错误消息

    #!/usr/bin/perl
    use strict;
    use warnings;
    my $filename = 'test.dat';
    open my $fh, $filename or die "Could not open file '$filename': $!";
    my @cols_to_change = qw ( 6 11 );
    while (my $val = <$fh>) {
       my @row = split (/,/);
       foreach my $col ( @cols_to_change ) {
          unless ( $row[$col] =~ m/\./ ) { $row[$col] .= '.' }
       }
    print join ( ',', @row );
    }
#/usr/bin/perl
严格使用;
使用警告;
my$filename='test.dat';
打开我的$fh、$filename或死亡“无法打开文件“$filename”:$!”;
my@cols_to_change=qw(6 11);
while(my$val=){
我的@row=拆分(/,/);
foreach my$col(@cols\u to\u change){
除非($row[$col]=~m/\./){$row[$col].='.}
}
打印联接(“,”,@行);
}
我收到的错误信息如下:

    20150202,abc,,,,3625.300000,,,,,-5,,,,,,,,,,,,,,,,,,,,,,
    20150202,def,,,,32.585,,,,,0,,,,,,,,,,,,,,,,,,,,,,
    20150202,xyz,,,,12,,,,,0.004167,,,,,,,,,,,,,,,,,,,,,,
Use of uninitialized value in split at test.pl line 11, <$fh> line 1.
Use of uninitialized value in pattern match (m//) at test.pl line 13, <$fh> line 1.
Use of uninitialized value in pattern match (m//) at test.pl line 13, <$fh> line 1.
Use of uninitialized value in join or string at test.pl line 15, <$fh> line 1.
....
在test.pl第11行第1行的拆分中使用未初始化值。
在test.pl第13行第1行的模式匹配(m/)中使用未初始化值。
在test.pl第13行第1行的模式匹配(m/)中使用未初始化值。
在test.pl第15行第1行的联接或字符串中使用未初始化的值。
....
我不允许使用任何额外的perl模块,如Text::CSV。此外,任何使用awk的解决方案都会有很大帮助

在awk中

只是那些领域的子

awk -F, -vOFS="," '{sub(/^[^\.]+$/,"&.",$6);sub(/^[^\.]+$/,"&.",$11)}1' file
或sed

sed 's/^\(\([^,]*,\)\{5\}[^.,]\+\),/\1./;s/^\(\([^,]*,\)\{10\}[^.,]\+\),/\1./' file
这是您的错误:

while (my $val = <$fh>) {
在上面的代码中-您正在while循环中设置
$val
,但是各种模式匹配和分割根本没有使用
$val

还要注意-perl数组中的第一个元素是
0
。因此,您可能应该保留复制的示例代码中的5和10

这:

按照要求,在输入样本数据时

为了完整性

  • 猛击

    (
        IFS=,
        while read -ra f; do 
            for i in 5 10; do 
                [[ ${f[i]} == *.* ]] || f[i]+=.   # add a dot if not there
            done
            echo "${f[*]}"                        # quotes required here
        done < file
    )
    
  • 下稿自:
    20150202,abc,,,,3625.300000,,,,,-5.,,,,,,,,,,,,,,,,,,,,,,
    20150202,def,,,,32.585,,,,,0.,,,,,,,,,,,,,,,,,,,,,,
    20150202,xyz,,,,12.,,,,,0.004167
    
    (
        IFS=,
        while read -ra f; do 
            for i in 5 10; do 
                [[ ${f[i]} == *.* ]] || f[i]+=.   # add a dot if not there
            done
            echo "${f[*]}"                        # quotes required here
        done < file
    )
    
    sed -r '
        s/^(([^,]*,){5})([^.,]+),/\1\3.,/
        s/^(([^,]*,){10})([^.,]+),/\1\3.,/
    ' file