轻松替换多个文件中的 with/without 正则表达式

Easy replace with/without regex in multiple files

我每天有数百次需要在文件中搜索模式,有时我不得不用其他东西替换这些模式。大多数时候它是简单的模式,比如一个词或一个短句,但有时我不得不寻找更复杂的正则表达式。我不太喜欢 sed(至少我的 sed 版本是这样,因为它不太符合 PCRE 引擎)。所以我更喜欢使用 perl -pi -e

但是,由于强制性的 -i.bak 临时文件,Perl pie 在 Cygwin 上并不是很有吸引力。我需要找到一种方法在处理后自动删除 .bak 文件。此外,如果我想在项目中递归替换,我必须先列出所有文件:

 find . | xargs -n1 perl -pi -e 's/foo/bar/'

这个命令写起来很长,特别是如果你一个月使用它一千次的话。所以我决定编写一个更有用的工具,其工作方式与伟大的白银搜索器 ag 相同。

 ag 'foo\d{3}[^\w]'  # Search for a pattern
 # Oh yes this one should be renamed!
 replace 's/(foo)\d{3}[^\w]/\U\E_bar/g'

我写了这个很原始的bash函数

function replace
{
  EXTENSION=.perlpie_tmp
  perl -p -i$EXTENSION -e  ${*:2}
  for file in ${*:2}; do 
    rm "$file$EXTENSION";
  done;
} 

但我一点都不满意,因为如果参数不超过一个,它不会自动递归搜索所有文件。如果参数的数量是 1,我可以修改这个函数并添加 find .,或者我可以用 Perl 编写一个非常复杂的程序,它可以支持命令行选项、漂亮的输出、智能案例搜索甚至纯文本搜索。

这个问题最合适的选择是什么?linux 世界上是否有任何高级 search/replace 工具?如果没有,我可能会尝试编写自己的 rip 工具来代表 replace-in-place,它可以支持我需要的所有选项。

在此之前我需要一些建议...

编辑

实际上我想分叉 https://github.com/petdance/ack2 以添加替换功能...这可能是个好主意也可能不是...

这是您函数的替代方法(已编辑为使用 the suggestion provided by gniourf_gniourf,谢谢):

find -type f . -exec sh -c 'perl -pi.bak -e "s/foo/bar/" "[=10=]" && rm -f "[=10=]".bak' {} \;

使用这种方法,您可以随时删除文件。

我觉得你可以用

grep -Hrn -e "string" . 

寻找规律,

find -type f -exec sed -i "s@string1@string2@g" {} \;

替换模式

我会稍微修改一下您现有的功能:

function replace {
  local  perl_code=  EXTENSION=.perlpie_tmp  file
  shift
  for file; do 
    perl -p -i$EXTENSION -e "$perl_code" "$file" && rm "$file$EXTENSION"
  done;
} 

这会稍微降低性能,因为您现在多次调用 perl,但我怀疑您不会注意到。