How do you use sed from Perl?

前端 未结 10 518
渐次进展
渐次进展 2021-01-18 01:14

I know how to use sed with grep, but within Perl the below fails. How can one get sed to work within a Perl program?

c         


        
10条回答
  •  深忆病人
    2021-01-18 01:39

    If you had a large sed expression, you could use s2p, to convert it into a perl program.

    If you run  <s2p 's/^\([0-9]*\)[:].*/\1/p'>, this is what you would get:

    #!/opt/perl/bin/perl -w
    eval 'exec /opt/perl/bin/perl -S $0 ${1+"$@"}'
      if 0;
    $0 =~ s/^.*?(\w+)[\.\w+]*$/$1/;
    
    use strict;
    use Symbol;
    use vars qw{ $isEOF $Hold %wFiles @Q $CondReg
             $doAutoPrint $doOpenWrite $doPrint };
    $doAutoPrint = 1;
    $doOpenWrite = 1;
    # prototypes
    sub openARGV();
    sub getsARGV(;\$);
    sub eofARGV();
    sub printQ();
    
    # Run: the sed loop reading input and applying the script
    #
    sub Run(){
        my( $h, $icnt, $s, $n );
        # hack (not unbreakable :-/) to avoid // matching an empty string
        my $z = "\000"; $z =~ /$z/;
        # Initialize.
        openARGV();
        $Hold    = '';
        $CondReg = 0;
        $doPrint = $doAutoPrint;
    CYCLE:
        while( getsARGV() ){
        chomp();
        $CondReg = 0;   # cleared on t
    BOS:;
    # s/^\([0-9]*\)[:].*/\1/p
    { $s = s /^(\d*)[:].*/${1}/s;
      $CondReg ||= $s;
      print $_, "\n" if $s;
    }
    EOS:    if( $doPrint ){
                print $_, "\n";
            } else {
            $doPrint = $doAutoPrint;
        }
            printQ() if @Q;
        }
    
        exit( 0 );
    }
    Run();
    
    # openARGV: open 1st input file
    #
    sub openARGV(){
        unshift( @ARGV, '-' ) unless @ARGV;
        my $file = shift( @ARGV );
        open( ARG, "<$file" )
        || die( "$0: can't open $file for reading ($!)\n" );
        $isEOF = 0;
    }
    
    # getsARGV: Read another input line into argument (default: $_).
    #           Move on to next input file, and reset EOF flag $isEOF.
    sub getsARGV(;\$){
        my $argref = @_ ? shift() : \$_; 
        while( $isEOF || ! defined( $$argref =  ) ){
        close( ARG );
        return 0 unless @ARGV;
        my $file = shift( @ARGV );
        open( ARG, "<$file" )
        || die( "$0: can't open $file for reading ($!)\n" );
        $isEOF = 0;
        }
        1;
    }
    
    # eofARGV: end-of-file test
    #
    sub eofARGV(){
        return @ARGV == 0 && ( $isEOF = eof( ARG ) );
    }
    
    # makeHandle: Generates another file handle for some file (given by its path)
    #             to be written due to a w command or an s command's w flag.
    sub makeHandle($){
        my( $path ) = @_;
        my $handle;
        if( ! exists( $wFiles{$path} ) || $wFiles{$path} eq '' ){
            $handle = $wFiles{$path} = gensym();
        if( $doOpenWrite ){
            if( ! open( $handle, ">$path" ) ){
            die( "$0: can't open $path for writing: ($!)\n" );
            }
        }
        } else {
            $handle = $wFiles{$path};
        }
        return $handle;
    }
    
    # printQ: Print queued output which is either a string or a reference
    #         to a pathname.
    sub printQ(){
        for my $q ( @Q ){
        if( ref( $q ) ){
                # flush open w files so that reading this file gets it all
            if( exists( $wFiles{$$q} ) && $wFiles{$$q} ne '' ){
            open( $wFiles{$$q}, ">>$$q" );
            }
                # copy file to stdout: slow, but safe
            if( open( RF, "<$$q" ) ){
            while( defined( my $line =  ) ){
                print $line;
            }
            close( RF );
            }
        } else {
            print $q;
        }
        }
        undef( @Q );
    }
    

    Not exactly worth doing on small expressions.

提交回复
热议问题