问题
I would like to read an input file and then delete a line if it matches my regex. and have the file saved without that line.
I have written
open(my $fh, '<:encoding(UTF-8)', $original_file_path or die "Could not open file $original_file_path $!";
while (my $line = <$fh> ) {
chomp $line;
if ($line ~=/myregex/){
delete line from file
}
}
Thank you
回答1:
You can modify a file in place by using -i
flag.
In your case, a simple one liner would do:
perl -i -ne 'print unless /myregex/' the_name_of_your_file
As mentioned by PerlDuck, if you wish to keep a copy the original file, it's possible: add an extension after the -i
flag, like -i.bak
or -i~
, and then original file will be kept with this extension after its name.
You can find more information about inplace file modification on perlrun.
Note that if you are using Windows (MS-DOS), you will need to specify an extension for the backup file, that you are free to delete afterward. See this link.
You can obtain the same behavior in a script by setting $^I
to a value different than undef
. For instance:
#!/usr/bin/perl
use strict;
use warnings 'all';
{
local @ARGV = ( $original_file_path );
local $^I = ''; # or set it to something else if you want to keep a backup
while (<>) {
print unless /myregex/
}
}
I've used local @ARGV
so if you already had something in @ARGV
, it won't cause any troubles. If @ARGV
was empty, then push @ARGV, $original_file_path
would be fine too.
However, if you have more stuff to do in your script, you might prefer a full script over a one-liner. In that case, you should read your input file, and print the lines you want to keep to another file, then move
the second file to the first.
回答2:
There are some modules that can make your life easier. E.g. here's a solution using Path::Tiny:
use Path::Tiny;
path($original_file_path)->edit_lines_utf8(sub {
if (/myregex/) {
$_ = '';
}
});
来源:https://stackoverflow.com/questions/42888145/edit-file-contents-in-perl