2016-05-23 22 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; 

を区切り文字;の5番目の出現。他のすべては変わらない必要があります。だから、所望の出力ファイルは、次のようになります。

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

私は人々がなぜ私をdownvotingしているのか知りません。下のすべての回答は希望の結果に達しましたが、私は1つしか受け入れることができません。 – 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()関数の最初の引数は文字列ではなく正規表現ですので、正規表現の区切り文字 '/.../'ではなく文字列区切り文字 '' ... "'をawkは文字列をregexpに変換してから使用する必要があります。 –

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

';'(セミコロン)を置き換える必要はありません。 'を置き換える必要があります。 5回目の ';'の後に '、'(コンマ)をつけて(完全停止)します。 – 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}\K)まで、すべてをスキップ
  2. と置換をaply。 、残りの行に($2 =~ s!\.!,!rg
関連する問題