简体   繁体   English

在Perl cript中运行sed命令时出错

[英]Error while running sed command in perl cript

I am trying to run the following command in perl script : 我试图在perl脚本中运行以下命令:

#!/usr/bin/perl

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

but is not producing any output nor any error. 但不会产生任何输出,也不会产生任何错误。 Although when I am running the command from command line it is working perfectly and gives desired output. 虽然当我从命令行运行命令时,它运行良好,并提供了所需的输出。 Can you guys please help what I am doing wrong here ? 你们能帮我在这里做错什么吗? Thanks 谢谢

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

To see the output, print $cmd3 . 要查看输出,请打印$cmd3

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

Edit: 编辑:
If you want to check for exceptional return values, use CPAN module IPC::System::Simple : 如果要检查异常的返回值,请使用CPAN模块IPC :: System :: Simple

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

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

Running sed from inside Perl is just insane. 从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;
}

Notice how Perl differs from your sed regex dialect in that grouping parentheses and alternation are unescaped, whereas a literal round parenthesis or pipe symbol needs to be backslash-escaped (or otherwise made into a literal, such as by putting it in a character class). 请注意,Perl与sed regex方言的不同之处在于, sed分组括号和替代符进行转义,而文字圆括号或管道符号则需要反斜杠转义(或以其他方式制成文字,例如将其放入字符类中)。 。 Also, the right-hand side of the substitution prefers $1 (you will get a warning if you use warnings and have \\1 in the substitution; technically, at this level, they are equivalent). 另外,替换的右侧更喜欢$1 (如果use warnings并且替换中有\\1 ,则会收到警告;从技术上讲,在此级别上,它们是等效的)。

man perlrun has a snippet explaining how to implement the -i option inside a script if you really need that, but it's rather cumbersome. man perlrun有一个片段,解释了如果您确实需要的话如何在脚本中实现-i选项,但这非常麻烦。 (Search for the first occurrence of " LINE: " which is part of the code you want.) (搜索第一次出现的“ LINE: ”,它是您想要的代码的一部分。)

However, if you want to modify file1 in-place, and you pass it to your Perl script as its sole command-line argument, you can simply say $^I = 1; 但是,如果要就地修改file1 ,并将其作为唯一的命令行参数传递给Perl脚本,则只需说$^I = 1; (or with use English; you can say $INPLACE_EDIT = 1; ). (或use English;您可以说$INPLACE_EDIT = 1; )。 See man perlvar . 参见man perlvar

By the way, the comment that your code "isn't producing any output" isn't entirely correct. 顺便说一句,关于您的代码“未产生任何输出”的注释并不完全正确。 It does what you are asking it to; 它可以满足您的要求; but you are apparently asking for the wrong things. 但是您显然是在要求错误的东西。

Quoting a command in backticks executes that command. 在反引号中引用命令将执行该命令。 So 所以

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

runs the sed command in a subshell, there and then, with input from file1 , and redirected into file2 . 在子外壳中运行sed命令,然后从file1输入,然后重定向到file2 Because of the redirection, the output from this pipeline is nothing, ie an empty string "" , which is assigned to $cmd3 , which you then completely superfluously attempt to pass to system . 由于重定向,该管道的输出为空,即为空字符串"" ,该字符串被分配给$cmd3 ,然后您完全可以将其完全多余地传递给system

Maybe you wanted to put the sed command in regular quotes instead of backticks (so that the sed command line would be the value of $cmd3 , which it then makes sense to pass to system ). 也许您想将sed命令放在正引号而不是反引号中(这样sed命令行将是$cmd3的值,然后将其传递给system )。 But because of the redirection, it would still not produce any visible output; 但是由于重定向,它仍然不会产生任何可见的输出。 it would create file2 containing the (possibly partially substituted) text from file1 . 它将创建包含file1 (可能是部分替换的)文本的file2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM