0

私はfile.txt次のように見えます:

C00010018;1;17/10/2013;17:00;18;920;113;NONE
C00010019;1;18/10/2013;17:00;18;920;0;NONE
C00010020;1;19/10/2013;19:00;18;920;0;NONE

そして、私は2つのことをしようとしています:

  1. 2 番目のフィールドとしてある行を選択し$id_playます。
  2. それらの行;で置き換えます。-

私の試み:

#!/usr/bin/perl

$id_play=3;
$input="./file.txt";
$result = `sed s@^\([^;]*\);$id_play;\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\)\$@\1-$id_play-\2-\3-\4-\5-\6@g $input`;

そして、私はこのエラーが発生しています:

sh: 1: Syntax error: "(" unexpected

なんで?

4

3 に答える 3

5

文字を@エスケープし、場合によっては 2 つのバックスラッシュを追加し (ysth に感謝します!)、sed の間に一重引用符を追加して、行もフィルタリングする必要があります。したがって、これに置き換えます:

$result = `sed 's\@^\\([^;]*\\);$id_play;\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\)\$\@\\1-$id_play-\\2-\\3-\\4-\\5-\\6-\\7\@g;tx;d;:x' $input`;

PS。あなたがやろうとしていることは、 splitsedを呼び出して使用することなく、よりクリーンな方法で達成できます。例えば:

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

my $id_play=3;
my $input="file.txt";
open (my $IN,'<',$input);
while (<$IN>) {
    my @row=split/;/;
    print join('-',@row) if $row[1]==$id_play;
}
close $IN;
于 2013-10-06T20:30:48.550 に答える
0

perl 正規表現エンジンが既に組み込まれており、はるかに使いやすいため、perl から sed を呼び出す必要はありません。上記の答えはまったく問題ありません。このような単純なデータセットを使用して、もう少し慣用的にそれを行う別の簡単な方法は次のようになります (ただし、もう少し難読化されている可能性があります...また、sed コマンド自体が少し複雑でした!)。

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

my $id_play = 3;
my @result = map { s/;/-/g; $_ } grep { /^\w+;$id_play;/ } <DATA>;
print @result;

__DATA__
C00010018;1;17/10/2013;17:00;18;920;113;NONE
C00010019;1;18/10/2013;17:00;18;920;0;NONE
C00010020;1;19/10/2013;19:00;18;920;0;NONE
C00010020;3;19/10/2013;19:00;18;920;0;NONE
C00010019;3;18/10/2013;17:00;18;920;0;NONE
C00010020;4;19/10/2013;19:00;3;920;0;NONE

ファイルがそれほど大きくないと仮定すると、正規表現で grep を使用して探している行を取得し、置換演算子でマッピングしてそれらのセミコロンをハイフンに変換し、結果をリストに保存できます。次に印刷します。コードの下のDATAブロックでテストしましたが、そのブロックから読み取る代わりに、通常どおりファイルから読み取ることになるでしょう。

edit : また、sed では、「(」と「)」は正規表現のグループ化ではなく、文字通りの通常の文字として扱われることを忘れていました。そのようなことのためにsedに夢中になっている場合は、sedの -r オプションを使用して、正規表現の意味でそれらの文字を使用させます。

于 2013-10-06T21:35:17.490 に答える
0
$ cat file
C00010018;1;17/10/2013;17:00;18;920;113;NONE
C00010019;2;18/10/2013;17:00;18;920;0;NONE
C00010020;3;19/10/2013;19:00;18;920;0;NONE
$ 
$ id_play=2                                                  
$ 
$ awk -v id="$id_play" -F';' -v OFS='-' '$2==id{$1=$1}1' file
C00010018;1;17/10/2013;17:00;18;920;113;NONE
C00010019-2-18/10/2013-17:00-18-920-0-NONE
C00010020;3;19/10/2013;19:00;18;920;0;NONE
于 2013-10-07T20:01:52.897 に答える