多线搜索替换为Perl

时间:2009-06-23 05:43:27

标签: 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;

3 个答案:

答案 0 :(得分:86)

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

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 documentation

如果您确实需要将其转换为工作程序,那么让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

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

答案 1 :(得分:2)

考虑到你在文件的全部内容中使用:

local $/ = undef;

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

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

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

答案 2 :(得分:1)

您可能想查看一下这个Perl脚本,该脚本经过了实战测试(在生产中大量使用),并且具有很多功能,例如:

  • 执行多个搜索替换或查询搜索替换操作
  • 搜索替换表达式可以在命令行上给出,也可以从文件中读取 处理多个输入文件
  • 递归地进入目录并对所有文件执行多个搜索/替换操作
  • 用户定义的perl表达式应用于每个输入文件的每一行 (可选)以段落模式运行(用于多行搜索/替换)
  • 互动模式
  • 批处理模式
  • 可选地备份文件和备份编号
  • 以超级用户身份运行时保留模式/所有者
  • 忽略符号链接,空文件,写受保护的文件,套接字,命名管道和目录名称
  • 可选地替换仅匹配/不匹配给定正则表达式的行

https://github.com/tilo/replace_string