Maestro815 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Guys, Would just like to ask for your wisdom on what approach can I do to make sed work with qx on a loop. It is working on the first loop but failing on the succeeding loops. Thanks in advance.

foreach (@SetBCs) { my $command = qx(sed -n "/Sets/,/Rules/p" $_); print $command; }

Replies are listed 'Best First'.
Re: qx + sed not working
by 1nickt (Canon) on Apr 20, 2018 at 12:44 UTC

    You don't need sed for that. Use Perl regexp substitution in your script. Or continue to use the shell, but with a Perl one-liner:

    $ perl -pi -e 's/Foo/Bar/' file1 file2 subdir1/file3
    See perlrun.


    The way forward always starts with a minimal test.
Re: qx + sed not working
by haukex (Archbishop) on Apr 20, 2018 at 12:46 UTC

    I can't test at the moment, but I wrote on the topic of running external commands here, including the advice to check $? for errors and that interpolating variables into the shell is problematic - what does @SetBCs contain exactly? But I think much more important here is: just do this in plain Perl in the first place, a while(<>) loop is fairly easy to implement (perlintro). At the very least you can switch to a module like IPC::System::Simple.

Re: qx + sed not working
by Anonymous Monk on Apr 20, 2018 at 12:13 UTC
    In what way, exactly, is it "failing on the succeeding loops?" What are the file-names in question? (Do any of them, for instance, contain spaces?) As usual, the devil is in the details. Show us a few of the filenames and give the exact error messages that you are seeing.

      Oh my, you're right. It is the blank lines that is causing the loop to stuck up.

      Files.txt contains the ff. lines: C:/ProcessFiles/File1.txt C:/ProcessFiles/File2.txt C:/ProcessFiles/File3.txt C:/ProcessFiles/File4.txt C:/ProcessFiles/File5.txt
      #!/usr/bin/perl use strict; use warnings; use File::Find; use Cwd; my @SetBCs; open(my $file, "<", "Files.txt") or die "Failed to open file: $!\n"; while(<$file>) { chomp; push @SetBCs, $_; } close $file; foreach (@SetBCs) { my $command = qx(sed -n "/Sets/,/Rules/p" $_); print $command; }

      Thanks!

        Without shelling out:

        #!/usr/bin/env perl use strict; use warnings; use Path::Tiny; chomp (my @SetBCs = <DATA>); for my $fname (@SetBCs) { next unless $fname; my @command = grep {/Sets/ .. /Rules/} path ($fname)->lines; print @command; } __DATA__ C:/ProcessFiles/File1.txt C:/ProcessFiles/File2.txt C:/ProcessFiles/File3.txt C:/ProcessFiles/File4.txt C:/ProcessFiles/File5.txt

        That's just one way. You can put your loading of @SetBCs back to reading from the file, but the rest of it should work fine as-is.

      Shame you didn't sign in for the one upvote I've given you in forever. :P

        The trend I see is that he tends to post relatively sane stuff anonymously, and downvote-bait logged in, which leads me to believe that he really is a troll. I mean, that is truly trollish behavior.

        Of course any regular here had the same thought, but you had to express it, start a thread hijack, rile up a round of kill-the-pig ... an anonymonk calls y'all on it, gets considered by the reigning chief bully, reaped, but you have to add the last word ...

        So a reasonable newb question is utterly drowned in garbage. The newb probably feels dirty somehow and won't be back, while anyone who comes to the thread via search will be all SMH at the tone. Congrats. You must really love this place.


        The way forward always starts with a minimal test.