Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Perl-在第n个分隔符后替换_Bash_Perl_Awk_Delimiter_Substitution - Fatal编程技术网

Bash Perl-在第n个分隔符后替换

Bash Perl-在第n个分隔符后替换,bash,perl,awk,delimiter,substitution,Bash,Perl,Awk,Delimiter,Substitution,我想获得一些关于替换的帮助,我想对如下文件行进行替换: aoipp;dadada.12312;ss;1245454;Xiop;12.12;45.3;47.897;31.5; asdfafd;14355.54664;peasd;125.1;900.2;76.897;67.456;asdfdf; perio;777.2;ipoes;900.34;2;1980.45;870.98;67.67; aoipp;dadada.12312;ss;1245454;Xiop;12,12;45,3;47,897;

我想获得一些关于替换的帮助,我想对如下文件行进行替换:

aoipp;dadada.12312;ss;1245454;Xiop;12.12;45.3;47.897;31.5;
asdfafd;14355.54664;peasd;125.1;900.2;76.897;67.456;asdfdf;
perio;777.2;ipoes;900.34;2;1980.45;870.98;67.67;
aoipp;dadada.12312;ss;1245454;Xiop;12,12;45,3;47,897;31,5;
asdfafd;14355.54664;peasd;125.1;900.2;76,897;67,456;asdfdf;
perio;777.2;ipoes;900.34;2;1980,45;870,98;67,67;
我想用
替换每个
,但仅在第五次出现分隔符
之后。其他一切都需要保持不变。因此,所需的输出文件如下所示:

aoipp;dadada.12312;ss;1245454;Xiop;12.12;45.3;47.897;31.5;
asdfafd;14355.54664;peasd;125.1;900.2;76.897;67.456;asdfdf;
perio;777.2;ipoes;900.34;2;1980.45;870.98;67.67;
aoipp;dadada.12312;ss;1245454;Xiop;12,12;45,3;47,897;31,5;
asdfafd;14355.54664;peasd;125.1;900.2;76,897;67,456;asdfdf;
perio;777.2;ipoes;900.34;2;1980,45;870,98;67,67;

我对主要用perl实现这一点很感兴趣,因此我可以将其合并到一个更大的程序中,但也欢迎使用bash/awk中的任何解决方案。提前感谢。

此awk one liner适用于您:

  # this should do your work
  sed -i 's/;/,/6g' filename

  cat filename
  aoipp;dadada.12312;ss;1245454;Xiop;12.12,45.3,47.897,31.5,
  asdfafd;14355.54664;peasd;125.1;900.2;76.897,67.456,asdfdf,
  perio;777.2;ipoes;900.34;2;1980.45,870.98,67.67,
awk -F';' -v OFS=";" '{for(i=6;i<=NF;i++)gsub("[.]",",",$i)}7' file

我使用数组切片
@fields[5..$#fields]
只访问要更改的元素

#!/usr/bin/perl
use warnings;
use strict;

my @input = qw( aoipp;dadada.12312;ss;1245454;Xiop;12.12;45.3;47.897;31.5;
                asdfafd;14355.54664;peasd;125.1;900.2;76.897;67.456;asdfdf;
                perio;777.2;ipoes;900.34;2;1980.45;870.98;67.67;
              );

my @expected = qw( aoipp;dadada.12312;ss;1245454;Xiop;12,12;45,3;47,897;31,5;
                   asdfafd;14355.54664;peasd;125.1;900.2;76,897;67,456;asdfdf;
                   perio;777.2;ipoes;900.34;2;1980,45;870,98;67,67;
                 );

sub process {
    my (@input) = @_;
    my @output;
    for my $line (@input) {
        my @fields = split /;/, $line;
        s/\./,/ for @fields[ 5 .. $#fields ];
        push @output, join ';', @fields, q();
    }
    return \@output
}

use Test::More tests => 1;
is_deeply(process(@input), \@expected);
while(我的$line=){
如果($line=~/^(?:[^;]*;){5}/){
substr($line,$+[0])=~y/,/;
}
打印$行;
}
__资料__
aoipp;dadada.12312;ss;1245454;Xiop;12.12;45.3;47.897;31.5;
asdfafd;14355.54664;豌豆;125.1;900.2;76.897;67.456;ASDFF;
佩里奥;777.2;首次公开募股;900.34;2.1980.45;870.98;67.67;
  • 跳过所有内容,直到第六个
    (.*){6}\K
  • 还有就是替代品,到行的其余部分(
    $2=~s!,!rg

  • 我不需要替换“;”在第五次出现“;”之后,我需要将“.”(句号)替换为“,”(逗号)。非常感谢你。最后的“7”有点让人困惑,但您的建议是有效的。@只有当它只进行打印时,awks*sub()函数的第一个参数才是regexp,而不是字符串,所以请使用regexp分隔符
    /…/
    而不是字符串分隔符
    “…”
    因为后者使您的代码更加复杂,因为awk必须在使用它之前将字符串转换为regexp。我不知道为什么人们一直对我投反对票。下面所有的答案都达到了预期的效果,但我只能接受一个。可能是因为你自己没有尝试解决这个问题。这很公平。我不知道需要多少正则表达式来处理这个问题。下次,当我开始提问时,我会发布一些失败的尝试。
    perl -pe 's/(.*?;){6}\K(.*)/$2 =~ s!\.!,!rg /ge'