it-swarm.dev

多线搜索替换为Perl

我知道这种问题之前已经被问过很多次了。我再次来到这里的原因是我觉得我错过了简单而基本的东西。

是否有可能更好地进行这种搜索替换程序。例如,两次不打开相同的文件。欢迎速度相关的建议。

请注意,这适用于多行匹配并替换多行字符串。

#!/bin/Perl -w -0777

local $/ = undef;

open INFILE, $full_file_path or die "Could not open file. $!";
$string =  <INFILE>;
close INFILE;

$string =~ s/START.*STOP/$replace_string/sm;

open OUTFILE, ">", $full_file_path or die "Could not open file. $!";
print OUTFILE ($string);
close OUTFILE;
50
user44556

这种搜索和替换可以通过单线程完成,例如 -

Perl -i -pe 's/START.*STOP/replace_string/g' file_to_change

有关完成相同操作的更多方法,请查看此 thread 。要处理多行搜索,请使用以下命令 -

Perl -i -pe 'BEGIN{undef $/;} s/START.*STOP/replace_string/smg' file_to_change

为了将以下代码从单行程序转换为Perl程序,请查看 perlrun文档

如果您确实需要将其转换为工作程序,那么让Perl为您处理文件打开/关闭。

#!/usr/bin/Perl -pi
#multi-line in place substitute - subs.pl
use strict;
use warnings;

BEGIN {undef $/;}

s/START.*STOP/replace_string/smg;

然后,您可以使用文件名作为第一个参数调用脚本

$Perl subs.pl file_to_change

如果你想要一个更加强大的脚本来处理文件打开/关闭操作(我们不喜欢所有那些'die'语句),那么看一下-l [extension]开关下的perlrun中的示例。

86
aks

对于那些寻找快速单行的人来说,从评论中得到简短的答案,以及Perl从命令行忽略他们的RegEx选项的原因。

Perl -0pe 's/search/replace/gms' file

如果没有-0参数,Perl会逐行处理data line ,这会导致多行搜索失败。

26
Beejor

考虑到您在文件的整个内容中使用以下内容进行Slurp:

local $/ = undef;

open INFILE, $full_file_path or die "Could not open file. $!";
$string =  <INFILE>;
close INFILE;

然后使用$string进行所有处理,处理文件的方式与处理内容的方式之间没有任何关联。如果在读完文件之前打开文件进行写入,则会出现问题,因为打开文件进行写入会创建新文件,丢弃以前的内容。

如果您要做的就是保存打开/关闭语句,那么请按照 Jonathan Leffer的建议 。如果您的问题是关于多行搜索和替换,那么请澄清问题所在。

2
Nathan Fellman