2016-05-23 63 views
-2

我想一些幫助,替換我想上的文件看起來像這樣的線路做:的Perl - 第n個分隔符之後替補

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的任何解決方案,亦歡迎。提前致謝。

+0

我不知道爲什麼人們低估我。下面所有的答案都達到了預期的結果,但我只能接受一個。 – onlyf

+2

可能因爲您沒有嘗試自己解決問題。 – Sobrique

+4

夠公平的。我不知道處理這個問題所需的正則表達式。下一次當我開始提問時,我會發布一些失敗的嘗試。 – onlyf

回答

3

這AWK的一行應該爲你工作:

awk -F';' -v OFS=";" '{for(i=6;i<=NF;i++)gsub("[.]",",",$i)}7' file 

它從第6場(;分開)開始,每場更換所有.通過,

測試與您的數據:

kent$ cat f 
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; 

kent$ awk -F';' -v OFS=";" '{for(i=6;i<=NF;i++)gsub("[.]",",",$i)}7' f 
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; 
+0

非常感謝。最後的'7'有點混亂,但你的建議是有效的。 – onlyf

+0

@onlyf它只是打印, – Kent

+1

awks * sub()函數的第一個arg是一個正則表達式,而不是一個字符串,所以使用正則表達式分隔符'/.../'而不是字符串分隔符'「...」後者讓你的代碼更加複雜,因爲awk必須在使用它之前將字符串轉換爲正則表達式。 –

0
# 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, 
+0

我不需要替換';'(分號)我需要替換'。' ('stop'),';'(逗號)在';'第五次出現之後。 – onlyf

3

我用了一個數組切片@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); 
3
while (my $line = <DATA>) { 
    if ($line =~ /^(?:[^;]*;){5}/) { 
     substr($line, $+[0]) =~ y/./,/; 
    } 
    print $line; 
} 
__DATA__ 
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; 
1
perl -pe 's/(.*?;){6}\K(.*)/$2 =~ s!\.!,!rg /ge' 
  1. 跳過一切,直到第6 ;(.*?;){6}\K),
  2. 和APLY替代。 ,到行的其餘部分($2 =~ s!\.!,!rg
相關問題