我需要每天一百次搜索文件中的模式,有时候我必须用其他东西替换这些模式。大多数时候它是简单的模式,如单词或短句,但有时我必须寻找更复杂的正则表达式。我不太喜欢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来添加替换功能......这可能是也可能不是一个好主意......
答案 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,但我怀疑你不会注意到。