Perl脚本中的复杂sed命令

时间:2017-08-01 19:03:19

标签: perl sed

我需要在Perl脚本中运行sed命令。但是因为sed命令很复杂,所以它不会在Perl中运行。但是,sed命令在shell中运行正常。

有人可以帮忙吗?

档案 -

  

cat / tmp / f1

"ABC": "abcd.com"
"Xris": [
"xyz.com"
"users": "user.com"
"id": "96444aa4b618.com"

shell上的sed命令 -

[]$ cat /tmp/f1 | sed  '/: \[.*$/ {s/\[//; N; s/\n//g; }'
"ABC": "abcd.com"
"XUrl": "xyz.com"
"users": "user.com"
"id": "96444aa4b618.com"
[]$

但是,当在Perl脚本中调用此sed命令时,它会抱怨。我尝试了许多不同的转义字符,但它不起作用。通常它会抛出错误 -

[]$ cat script.pl
#!/usr/bin/perl
`sed -e '/: \[.*$/ {s/\[//; N; s/\n//g; }' /tmp/f1`;
[]$ ./script.pl
sed: -e expression #1, char 6: unterminated address regex
[]$

请帮助了解如何在Perl脚本中运行此sed命令。或者有更好的方法在Perl脚本中运行sed吗?

3 个答案:

答案 0 :(得分:3)

Perl可以完成您使用sed进行的转换,几乎可以轻松完成。我怀疑这是否是最小的Perl,但它适用于样本数据,除了它没有将Xris映射到XUrl(我认为这是问题中的拼写错误)。

#!/usr/bin/env perl

use strict;
use warnings;

while (<>)
{
    if (m/: \[.*$/)
    {
        chomp;
        my $next = <>;
        $_ =~ s/: \[.*/: /;
        $_ .= $next;
    }
    print;
}

当从问题运行数据文件时,输出为:

"ABC": "abcd.com"
"Xris": "xyz.com"
"users": "user.com"
"id": "96444aa4b618.com"

这几乎是想要的。您可以修改代码,以便chomp不是必需的,但您需要删除$_语句中if末尾的换行符:

#!/usr/bin/env perl

use strict;
use warnings;

while (<>)
{
    if (m/: \[.*$/)
    {
        my $next = <>;
        $_ =~ s/: \[.*\n/: /;
        $_ .= $next;
    }
    print;
}

来自同一输入的相同输出。

答案 1 :(得分:2)

反引号插入和处理转义就像双引号一样,所以

`sed -e '/: \[.*$/ {s/\[//; N; s/\n//g; }' /tmp/f1`

相同
`sed -e '/: [.*
{s/[//; N; s/
//g; }' /tmp/f1`

你需要

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote('sed', '-e', '/: \\[.*$/ {s/\\[//; N; s/\\n//g; }', '/tmp/f1');
my $output = `$cmd`;
die("sed killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("sed exited with error ".( $? >> 8 )."\n") if $? >> 8;

当然,sed可以做的任何事情都可以在Perl中轻松完成。你最好这样做。

答案 2 :(得分:0)

谢谢大家..

对不起,问题中有拼写错误。

将sed命令替换为以下,现在它正常工作 -

while (<>)
{
    if (m/: \[.*$/)
    {
        my $next = <>;
        $_ =~ s/: \[.*\n/: /;
        $_ .= $next;
    }
    print;
}