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

want to run the following sed command with backticks to remove commas from file that is created - not sure how to run a sed command within perl. Any idea?
#!/usr/bin/perl my $target = '/tmp/filetest'; my @sources = <*pol.txt>;; die "Usage: $0 in in ... in out\n" if not @sources; open my $out, '>>', $target or die "Could not open '$target' for appen +ding\n"; foreach my $file (@sources) { if (open my $in, '<', $file) { while (my $line = <$in>) { `sed 's/\(.*\),/\1/'`; print $out $line; } close $in; } else { warn "Could not open '$file' for reading\n"; } } close $out; `sort /tmp/filetest -o /tmp/filetest`; #print "done\n";

Replies are listed 'Best First'.
Re: sed command in perl
by stevieb (Canon) on Jun 08, 2016 at 21:08 UTC

    Perl takes a lot from `sed` already, so no need to shell out.

    Without seeing your data it's hard to tell what you're trying to do exactly, but I'll assume you want to replace the comma at the end of the string.

    Replace:

    `sed 's/\(.*\),/\1/'`;

    with...

    s/,$//;

    If that doesn't do what you want, supply a bit of the input file, and what your expected output should look like. Put both within <code></code> tags as you have with your code.

    Also explain what you're trying to do with sort as well, as that can be avoided too.

      What I want to do is remove the last comma in the file: for example:
      21112,/vol/voly,blx 21113,/vol/eng,blz 21114,/vol/eng,file
      I want the second comma to be gone. It is not at the end of the line.

        If you have Perl version 5.10 or later, this also works:

        c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; for my $s ('21112,/vol/voly,blx', '21113,/vol/eng,blz', '21114,/vol +/eng,file') { my $t = $s; $t =~ s{ .* \K , }{}xms; print qq{'$s' -> '$t'}; } " '21112,/vol/voly,blx' -> '21112,/vol/volyblx' '21113,/vol/eng,blz' -> '21113,/vol/engblz' '21114,/vol/eng,file' -> '21114,/vol/engfile'

        Update: Slightly changed code example to enhance clarity.


        Give a man a fish:  <%-{-{-{-<

        G'day novice2015,

        TMTOWTDI:

        #!/usr/bin/env perl use strict; use warnings; while (my $init_line = <DATA>) { my $neg_class_line = $init_line; my $neg_assert_line = $init_line; $neg_class_line =~ s/,([^,]*)$/$1/; $neg_assert_line =~ s/,(?!.*,)//; print 'Initial line: ', $init_line; print 'Negated class: ', $neg_class_line; print 'Negative assertion: ', $neg_assert_line; print '-' x 40, "\n"; } __DATA__ 21112,/vol/voly,blx 21113,/vol/eng,blz 21114,/vol/eng,file

        Output:

        Initial line: 21112,/vol/voly,blx Negated class: 21112,/vol/volyblx Negative assertion: 21112,/vol/volyblx ---------------------------------------- Initial line: 21113,/vol/eng,blz Negated class: 21113,/vol/engblz Negative assertion: 21113,/vol/engblz ---------------------------------------- Initial line: 21114,/vol/eng,file Negated class: 21114,/vol/engfile Negative assertion: 21114,/vol/engfile ----------------------------------------

        See perlre for a description of these, and other, methods.

        Use Benchmark to find the most efficient method (if that's important to you).

        And finally, a quick, friendly note on being specific. In one place you say "last comma" and in another you say "second comma": in the current (or future) data, these may not be the same. My two examples operate on the last comma (or change nothing if no commas are present). Adding these additional DATA lines:

        W,X,Y,Z W,X,YZ W,XYZ WXYZ

        I get this additional output:

        Initial line: W,X,Y,Z Negated class: W,X,YZ Negative assertion: W,X,YZ ---------------------------------------- Initial line: W,X,YZ Negated class: W,XYZ Negative assertion: W,XYZ ---------------------------------------- Initial line: W,XYZ Negated class: WXYZ Negative assertion: WXYZ ---------------------------------------- Initial line: WXYZ Negated class: WXYZ Negative assertion: WXYZ ----------------------------------------

        — Ken

        Gotcha... then this will look really similar. Just replace the whole sed line with: s/(.*),/$1/;