Vieypul
Vieypul

Reputation: 29

Error while running sed command in perl cript

I am trying to run the following command in perl script :

#!/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

Upvotes: 1

Views: 86

Answers (3)

tripleee
tripleee

Reputation: 189915

Running sed from inside Perl is just insane.

#!/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). 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).

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. (Search for the first occurrence of "LINE:" which is part of the code you want.)

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; (or with use English; you can say $INPLACE_EDIT = 1;). See 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. Because of the redirection, the output from this pipeline is nothing, i.e. an empty string "", which is assigned to $cmd3, which you then completely superfluously attempt to pass to 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). 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.

Upvotes: 0

serenesat
serenesat

Reputation: 4709

To see the output, print $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:

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

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

Upvotes: 1

Juan Diego Godoy Robles
Juan Diego Godoy Robles

Reputation: 14975

system() doesn't return the output, just the exit status.

Upvotes: 1

Related Questions