首页 > 解决方案 > find a digit in $_ and add data to $_ in perl

问题描述

I am trying to read data from a file using File I/O in perl. I want to find an integer, compare it and add a integer to the line. My file consists of line like this.

file mfile.txt start_value 0 end_value 13000 errors 30

I want to compare the end_value and want to add 500 or 2000 after that end_value.

file mfile.txt start_value 0 end_value 13000 2000 errors 30

This edit has to be done in the same file. My code goes like this.

print "Enter file ";
$file= <STDIN>;
chomp ($file);

open ( DATA, "+<$file") || die "No file";

while(<DATA>) {
   print "$_\n";    
   @line = split / /, $_; 
   print "$line[5]";
   $epat = $line[5];
   if ($epat > 10000) {
       $line[6] = "2000 errors";
   }
   else {
       $line[6] = "500 errors";
   }
   $_ = join (" ", @line);
   print "$_";
   print "\n";
}

close DATA

I tried to convert $_ to array and find the end_value by calling its index and compare it. It worked fine but how to write this new edit to the same line in the same file? After this the file is not changed. How to do that?

标签: perlfile-io

解决方案


You can use perl -i to change the file in place, but you then need to populate @ARGV with the filename. It writes to another file and renames it back behind the scenes, anyway.

In fact, you can use just a one-liner:

perl -i~ -ape 's/(?=errors)/$F[5] > 10000 ? "2000 " : "500 "/e' -- filename
  • -i~ creates a backup of the file using the suffix ~
  • -a splits each line into the @F array
  • -p reads the input or argument files line by line and prints each line after processing
  • s///e does substitution, but interprets the replacement as code to run
  • (?=errors) is a look-ahead assertion, it matches where "errors" start, but doesn't replace the matching part
  • ? : is the ternary operator, it corresponds to an if then else on the expression level

推荐阅读