【问题标题】:Sed command in perl scriptperl 脚本中的 sed 命令
【发布时间】:2018-08-17 09:06:30
【问题描述】:

我正在尝试使用我的 Perl 脚本中的 sed 命令。我必须从 25GB 的文件中获取最后一小时的数据,但是当我从终端运行相同的命令时,它工作正常,但相同的命令在 Perl 脚本中不起作用。我正在使用的系统变量,这导致了我认为的问题,不知道如何处理:

my $sed_cmd = 'sed -n "/'.$last_hour.'/,\$p"';
my $outstr=`ssh $remote_addr $sed_cmd  $dir/$remote_filename`;

上面的命令被转换成这样:sed -n "/15:12:24/,\$p" 并且从 perl 脚本这不起作用。 但实际上这个命令是从终端工作的:sed -n "/15:09:40/,\$p" file

唯一的区别是当我用 ssh 调用这个 sed 命令时我得到错误,否则它工作正常。你能建议是什么问题

【问题讨论】:

  • perl 可以处理,为什么要调用sed
  • 可能是my $sed_cmd=quotemeta('sed -n "/'.$last_hour.'/,\$p"')?
  • 伙计们,他正在使用 ssh 将 sed 命令发送到远程主机。冷静。
  • @anubhava,您能否建议我们如何从 perl 而不是使用 sed 做到这一点。我想 grep 上一小时打印的所有行
  • @wolfrevokcats quotemeta 为我工作

标签: bash perl unix sed


【解决方案1】:

我认为您遇到了一些用反引号引用地狱的问题,您需要将 ssh 命令及其所有参数连接成一个字符串以发送到 sh。我建议这样做,其中 ssh 命令的每个组件都是一个单独的词:

use autodie;

my @ssh_cmd = ('ssh', $remote_addr, 'sed', '-n', "/$last_hour/,\\\$p", "$dir/$remote_filename");
open my $pipe, '-|', @ssh_cmd;
my $outstr = join '', <$pipe>;
close $pipe;

【讨论】:

    【解决方案2】:

    您可以使用Net::OpenSSH。它会自动处理shell escaping

    my $ssh = Net::OpenSSH->new($remote_addr);
    my $outstr = $ssh->capture('sed', '-n', "/$last_hour/,\$p", "$dir/$remote_file");
    

    顺便说一句,读取 25Gb 文件只是为了从末尾获取一些行可能效率低下并产生可观的 IO 负载。也许您可以使用 tac 以相反的顺序读取文件行:

    my $ssh = Net::OpenSSH->new($remote_addr);
    my $fh = $ssh->pipe_out('tac', "$dir/$remote_file");
    my @out;
    while (<$fh>) {
        /$last_hour/ or last; # you may need to adjust this
                              # stop condition!
        unshift @out, $_;
    }
    close($fh);
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 2018-01-08
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      相关资源
      最近更新 更多