在多个文件中使用/不使用正则表达式轻松替换

时间:2015-01-24 11:40:53

标签: linux bash

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

然而,由于强制性的-i.bak临时文件,Perl派对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$1\E_bar/g'

我写了这个非常原始的bash函数

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

但我完全不满意,因为如果没有多个参数,它不会自动搜索所有文件。如果参数的数量为find .,我可以将此函数修改为添加1,或者我可以在Perl中编写一个可以支持命令行选项,漂亮输出,智能案例搜索甚至更复杂的程序纯文本搜索。

这个问题最合适的选择是什么?Linux世界中是否有任何高级搜索/替换工具?如果不是,我可以尝试编写我自己的rip工具代表replace-in-place,它可以支持我需要的所有选项。

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

编辑

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

3 个答案:

答案 0 :(得分:3)

这是您的功能的替代方案(编辑后使用the suggestion provided by gniourf_gniourf,谢谢):

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

使用此方法,您可以随时删除该文件。

答案 1 :(得分:0)

我认为你可以使用

grep -Hrn -e "string" . 

找到一个模式,

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

替换模式

答案 2 :(得分:0)

我会略微修改你现有的功能:

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

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