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

我正在尝试做两件事:

  1. 选择具有$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。您可以通过更干净的方式实现您想要做的事情,而无需调用sed和使用split。例如:

#!/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 调用 sed,因为 perl 正则表达式引擎已经内置并且更易于使用。上面的答案完全没问题。有了这样一个简单的数据集,另一种更惯用的简单方法(尽管可能更模糊......那么 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块对其进行了测试,但不是从该块中读取,您可能会照常从文件中读取。

编辑:还忘了提到在 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 回答