How can I conditionally replace a string with one word using Perl?

I want to replace the lines ending with "YES", "YES" and replace the lines ending with "NO" with "NO". 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  

Exit:

  Yes
 NO
 NO 
+4
source share
6 answers
perl -p -e 's/.*(YES|NO)\s*$/$1/;' 

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

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

To learn more about perl regular expressions, wildcards, etc., see "perldoc perlre" from the command line of your system where perl is installed

+1
source

Although Paul answers correctly, I would like to point out that there is another way to look at your problem. Your question indicates that the line ends with "YES" or "NO". So one more 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 lines ended with YES or NO. If this is true for all lines in your input, this can be simplified to:

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

A brief explanation of the Perl command line flags used (you can also read this in perloc perlrun):

  • -l is used to automatically split input lines and add "\ n" when printing. A.
  • -a automatically splits the input string in a space into an @F array when used with "-n" or "-p".
  • -p creates a loop that runs along the lines of the given input file / s and does a โ€œprintโ€ at the end after running your code.
  • -e is, of course, a flag for providing code on the command line

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

My goal was not to play Perl Golf and show you a shorter way to answer your question, instead I'm trying to point out that just thinking about a problem from a slightly different angle can show you different ways to solve it, which may be better / more elegant. Therefore, please do not focus on which solution is shorter, but think about how different people attacked even this simple problem from different directions and how you can do the same.

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

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

Matching in a 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 'Y' or 'N' , there are two options. One of them is to use two capture buffers and use grep to filter a substring that does not match:

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

or, even better, use a named capture buffer:

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

Conclusion:

  Y
 N
 N 
+2
source

This is for you if you need it.

 awk '{print $NF}' file_name 
+1
source

You can also use the following code

 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 delete "\ n". After that, I checked that the end of the line contains โ€œYESโ€ or โ€œNOโ€

+1
source

Most published answers use the s/// substitution to change the value of a string. Although this does work, it is not easy to maintain. Therefore, 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
source

Source: https://habr.com/ru/post/1300609/


All Articles