5

The following command work fine on Solaris ( delete line only if last character is ":" )

 sed -e '/:$/d' < foo > foo.new

how to do the same in perl ? ( the reason for that because I not want to create a new file )

  perl -i -pe 's/:$/d' foo
  Substitution replacement not terminated at -e line 1.
yael
  • 91

3 Answers3

7

Something similar to:

perl -ne 'print unless /:$/'
perl -ne 'print if !/:$/'
perl -ne '!/:$/ && print'

Note that both sed -i and perl -i work by creating a temporary file and replacing the original. If you want to avoid that, too, use ed:

ed file <<'EOF'
g/:$/d
wq
EOF
grawity
  • 501,077
3

Perl comes with a sed-to-perl translator, s2p. Just for interest, s2p '/:$/d' gives:

#!/usr/local/bin/perl -w
eval 'exec /usr/local/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:;

/:$/d

if( m /:$/s ) { $doPrint = 0; goto EOS; }

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 = <ARG> ) ){ 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 = <RF> ) ){ print $line; } close( RF ); } } else { print $q; } } undef( @Q ); }

glenn jackman
  • 27,524
0

Delete line if last character is ":"

perl -i -nle'/:$/||print' myfile
perl -i -nle'print unless /:$/' myfile            #same thing

Go to http://perldoc.perl.org/perlrun.html for explanations on -i -n -l and -e.

Kjetil S.
  • 609