![如何在 Linux 中替换多个文件中的文本字符串](https://linux22.com/image/495065/%E5%A6%82%E4%BD%95%E5%9C%A8%20Linux%20%E4%B8%AD%E6%9B%BF%E6%8D%A2%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%96%87%E6%9C%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
有多种方法可以将多个文件中的一串文本替换为另一串文本。以下是几种方法:
使用 sed 并查找:
sed 's/oldstring/newstring/' "$1" > "$1".new && find -iname "*.new" | sed 's/.new//' | sh
使用 grep 和 sed:
grep -rl oldstring . | xargs sed -i -e 's/oldstring/newstring/'
使用 grep 和 perl:
grep -rl oldstring . | xargs perl -pi~ -e 's/oldstring/newstring/'
请提出您自己的建议。
答案1
我会使用 Python 来实现这一点。将所有代码放入名为 mass_replace 和“ ”的文件中chmod +x mass_replace
:
#!/usr/bin/python
import os
import re
import sys
def file_replace(fname, s_before, s_after):
out_fname = fname + ".tmp"
out = open(out_fname, "w")
for line in open(fname):
out.write(re.sub(s_before, s_after, line))
out.close()
os.rename(out_fname, fname)
def mass_replace(dir_name, s_before, s_after):
for dirpath, dirnames, filenames in os.walk(dir_name):
for fname in filenames:
f = fname.lower()
# example: limit replace to .txt, .c, and .h files
if f.endswith(".txt") or f.endswith(".c") or f.endswith(".h"):
f = os.path.join(dirpath, fname)
file_replace(f, s_before, s_after)
if len(sys.argv) != 4:
u = "Usage: mass_replace <dir_name> <string_before> <string_after>\n"
sys.stderr.write(u)
sys.exit(1)
mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])
对于在一种类型的文件中搜索和替换一个字符串,使用 find 和 sed 的解决方案还不错。但是如果您想一次性完成大量处理,您可以编辑此程序来扩展它,这将很容易(并且第一次就可能正确)。
答案2
像这样使用 GNU find、xargs 和 sed:
find -name '*.txt' -o -name '*.html' -print0 | xargs -0 -P 1 -n 10 sed --in-place 's/oldstring/newstring/g'
根据需要调整-P
和参数。需要的是,这样一行中的每个出现都会被替换,而不仅仅是第一个(代表-n
/g
g
全球的如果我没记错的话)。您还可以传递一个值来--in-place
进行备份。
答案3
我喜欢 perl 的就地过滤配方。
perl -pi.bak -e 's/from/to/' 文件1 文件2 ...
在上下文中...
% echo -e 'foo\ngoo\nboo' >test
% perl -pi.bak -e 's/goo/ber/' test
% diff -u test.bak test
--- test.bak 2010-01-06 05:43:53.072335686 -0800
+++ test 2010-01-06 05:44:03.751585440 -0800
@@ -1,3 +1,3 @@
foo
-goo
+ber
boo
这里是关于使用的 perl 咒语的精简快速参考...
% perl --help
Usage: perl [switches] [--] [programfile] [arguments]
-e program one line of program (several -e's allowed, omit programfile)
-i[extension] edit <> files in place (makes backup if extension supplied)
-n assume "while (<>) { ... }" loop around program
-p assume loop like -n but print line also, like sed
答案4
如果用“/”字符替换 URL,请小心。
如何操作的一个例子:
sed -i "s%http://domain.com%http://www.domain.com/folder/%g" "test.txt"
摘自:http://www.sysadmit.com/2015/07/linux-reemplazar-texto-en-archivos-con-sed.html