【问题标题】:Error while running sed command in perl cript在 perl 脚本中运行 sed 命令时出错
【发布时间】:2015-04-16 12:08:07
【问题描述】:

我正在尝试在 perl 脚本中运行以下命令:

#!/usr/bin/perl

my $cmd3 =`sed ':cycle s/^\(\([^,]*,\)\{0,13\}[^,|]*\)|[^,]*/\1/;t cycle' file1 >file2`;
 system($cmd3);

但没有产生任何输出或任何错误。 尽管当我从命令行运行命令时,它运行良好并提供了所需的输出。你们能帮我在这里做错什么吗? 谢谢

【问题讨论】:

  • Perl 是sed 的超集,因此涉及sed 根本没有任何意义。 perl -pe '1 while s/^(([^,]*,){0,13}[^,|]*)\|[^,]*/$1/' file1 >file2
  • @tripleee 谢谢,我会接受你的建议。我不知道 Perl 是 sed 的超集。它是为我写的,但有什么选项可以像我们在 sed "i" 中将输出写回同一个文件一样。再次感谢!
  • @tripleee 此 perl 命令也不适用于 perl 脚本。但我可以在命令行上使用它。我应该修改什么才能在 perl 脚本中运行?
  • Perl -i 就像(有时)sed -i 一样可用;但是当然重定向到file2 没有任何意义。
  • @tripleee 谢谢,但是这个命令在 perl 脚本中不起作用。我怎样才能做到这一点?

标签: perl shell awk sed


【解决方案1】:

system() 不返回输出,只返回exit 状态。

【讨论】:

  • 感谢您的快速回复。那么如何在 perl 脚本本身中运行命令。
【解决方案2】:

要查看输出,请打印$cmd3

my $cmd3 = `sed ':cycle s/^\(\([^,]*,\)\{0,13\}[^,|]*\)|[^,]*/\1/;t cycle' file1 >file2`;
print "$cmd3\n";

编辑:
如果要检查异常返回值,请使用 CPAN 模块IPC::System::Simple

use IPC::System::Simple qw(capture);

my $result = capture("any-command"); 

【讨论】:

    【解决方案3】:

    从 Perl 内部运行 sed 简直是疯了。

    #!/usr/bin/perl
    
    open (F, '<', "file1") or die "$O: Could not open file1: $!\n";
    while (<F>) {
        1 while s/^(([^,]*,){0,13}[^,|]*)\|[^,]*/$1/;
        print;
    }
    

    请注意 Perl 与您的 sed 正则表达式方言的不同之处在于分组括号和交替是未转义的,而文字圆括号或管道符号需要反斜杠转义(或以其他方式制成文字,例如将其在字符类中)。此外,替换的右侧更喜欢$1(如果您在替换中使用use warnings 并有\1,则会收到警告;从技术上讲,在这个级别上,它们是等效的)。

    man perlrun 有一个 sn-p 解释如何在脚本中实现 -i 选项,如果你真的需要的话,但它相当麻烦。 (搜索第一次出现的“LINE:”,这是您想要的代码的一部分。)

    但是,如果您想就地修改 file1,并将其作为唯一的命令行参数传递给您的 Perl 脚本,您可以简单地说 $^I = 1;(或者使用 use English;,您可以说 @ 987654335@)。见man perlvar

    顺便说一句,您的代码“没有产生任何输出”的评论并不完全正确。它按照您的要求执行;但你显然是在要求错误的东西。

    在反引号中引用命令会执行该命令。所以

    my $cmd3 = `sed ... file1 >file2`;
    

    在子shell 中运行sed 命令,然后使用来自file1 的输入,并重定向到file2。由于重定向,该管道的输出什么都不是,即一个空字符串"",它被分配给$cmd3,然后您完全多余地尝试将其传递给system

    也许您想将sed 命令放在常规引号而不是反引号中(这样sed 命令行将是$cmd3 的值,然后将其传递给system 是有意义的)。但是由于重定向,它仍然不会产生任何可见的输出;它将创建 file2 包含来自 file1 的(可能部分替换的)文本。

    【讨论】:

    • 您的问题并没有具体询问-i,但它在评论中。如果您需要将内联替换作为较大脚本的一部分,调用一个优雅地执行此操作的外部工具开始看起来不那么疯狂了。
    猜你喜欢
    • 2014-03-24
    • 2018-08-17
    • 2020-09-04
    • 2018-03-25
    • 1970-01-01
    • 2017-05-30
    • 2017-03-15
    • 2018-01-08
    • 2013-07-18
    相关资源
    最近更新 更多