开发者

How can I conditionally replace a line with a single word using Perl?

I want to replace a lines that ends with 'YES' with 'YES' and replace lines that ends with 'NO'with 'NO'. 开发者_JS百科I have to apply for a large file.

Input:

 max. C    13       0.457   0.32   YES
 max. Y    13       0.232   0.33   NO
 max. S     1       0.315   0.87   NO  

Output:

YES
NO
NO


While Paul's answer is correct, I wanted to point out there was another way to look at your problem. Your question states that the line ends with "YES" or "NO". Therefore another thing you could do is split the line and print the last element, if it matches "YES" or "NO":

perl -lape'$_=$F[-1] if $F[-1]=~m/^(?:YES|NO)$/'

In your example, all the lines ended in YES or NO. If this is really the case for all lines in your input, this can be simplified to:

perl -lape'$_=$F[-1]'

A short explanation of the Perl command-line flags used (you can also read this at "perldoc perlrun"):

  • -l is used to automatically chomp the input strings and append "\n" when printing.
  • -a auto-splits the input line on whitespace into the @F array, when used together with "-n" or "-p".
  • -p creates a loop that runs over the lines of the given input file/s and does a "print" at the end after your code is run.
  • -e is of course the flag for giving code on the command line

So basically the command-line flags do most of the work. The only thing I have to do is assign $F[-1] (the last element of the line) into $_ which is the thing which will be printed thanks to "-p".

My goal wasn't to play Perl Golf and show you a shorter way of answering your question, instead I'm trying to point out that simply thinking about a problem from a slightly different angle can show you different ways to solve it, which might be better/more elegant. So please don't focus on which solution is shorter, instead think about how different people attacked even this simple problem from different directions and how you can do the same.

One more point, you wrote "I want to replace a lines". If you meant replace in the input file itself, the "-i" (in-place replace) command-line flag is your friend:

perl -lapi.bak -e'$_=$F[-1]'


Match in list context returns captured substrings:

#!/usr/bin/perl

use strict; use warnings;

while ( <DATA> ) {
    if (my ($resp) = /(YES|NO)\s+\z/) {
        print "$resp\n";
    }
}

__DATA__
 max. C    13       0.457   0.32   YES
 max. Y    13       0.232   0.33   NO
 max. S     1       0.315   0.87   NO

And, if you just wanted to capture the 'Y' or 'N', there are two options. One is to use two capture buffers and use grep to filer out the substring that did not match:

if (my ($resp) = grep defined, /(?:(Y)ES)|(?:(N)O)\s+\z/ ) {
    print "$resp\n";
}

or, better yet, use a named capture buffer:

if ( /(?: (?<resp>Y) ES) | (?: (?<resp>N) O) \s+\z/x ) {
    print "$+{resp}\n";
}

Output:

Y
N
N


perl -p -e 's/.*(YES|NO)\s*$/$1/;' 

If you want Y and N instead of YES and NO then change it to

s/.*(Y|N)[ESO]+$/$1/;

To read more about perl regular expressions, substitions, etc. check out "perldoc perlre" from the command line of your system where perl is installed


This is upto you if you need it.

awk '{print $NF}' file_name


You can use the following code also,

use strict;
use warnings;
my $var;
open (FH,"<file") or die "$! can't open";
while($var=<FH>)
{
     chomp($var);
     $var=~s/.*(YES|NO)$/$1/;
     print "$var\n";
}

In this code I used the chomp function. This function is used to remove the "\n". After that I checked the end of the line contains "YES" or "NO"


A lot of the the posted answers use substitution s/// to change the value of the line. While this does work, it isn't easy to maintain. So why not just set the string to YES or NO after a successful match.

use strict;
use warnings;
use autodie;

my $filename = 'file'

{
  open my $fh, '<', $filename;
  while( my $line = <$fh> ){
     chomp($line);

     if( $line =~ /(YES|NO)$/ ){
       $line = $1;
     }

     print $line, "\n";
  }
  close $fh;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜