我需要在目录内的所有文件和子目录中递归搜索指定的字符串,并将该字符串替换为另一个字符串。
我知道找到它的命令可能如下所示:
grep 'string_to_find' -r ./*
但是我怎样才能string_to_find
用另一个字符串替换每个实例呢?
另一种选择是使用 find 然后通过 sed 传递它。
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;
我得到了答案。
grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
You could even do it like this:
Example
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
This will search for the string 'windows' in all files relative to the current directory and replace 'windows' with 'linux' for each occurrence of the string in each file.
这在 OS X 上最适合我:
grep -r -l 'searchtext' . | sort | uniq | xargs perl -e "s/matchtext/replacetext/" -pi
资料来源: http: //www.praj.com.au/post/23691181208/grep-replace-text-string-in-files
通常不使用 grep,而是使用sed -i 's/string_to_find/another_string/g'
or perl -i.bak -pe 's/string_to_find/another_string/g'
。
其他解决方案混合了正则表达式语法。要使用 perl/PCRE 模式进行搜索和替换,并且只处理匹配的文件,这非常有效:
grep -rlIZPi 'match1' | xargs -0r perl -pi -e 's/match2/replace/gi;'
match1
并且match2
通常相同,但match2
可以包含仅与替换相关的更高级功能,例如捕获组。
翻译:grep
递归并列出匹配的文件名,每个都用空分隔以保护任何特殊字符;管道任何xargs
需要空分隔列表的文件名;如果收到任何文件名,请将它们传递perl
给执行实际替换。
对于区分大小写的匹配,从表达式中删除i
标志grep
和i
模式修饰符s///
,但不要i
从其perl
自身中删除标志。要包含二进制文件,请I
从grep
.
在 git repo 中使用find
和使用时要非常小心!sed
如果您不排除二进制文件,则可能会出现此错误:
error: bad index file sha1 signature
fatal: index file corrupt
要解决此错误,您需要sed
通过将您的替换new_string
为您的old_string
. 这将还原您替换的字符串,因此您将回到问题的开头。
搜索字符串并替换它的正确方法是跳过find
并grep
改为使用以忽略二进制文件:
sed -ri -e "s/old_string/new_string/g" $(grep -Elr --binary-files=without-match "old_string" "/files_dir")
@hobs 的学分
这是我要做的:
find /path/to/dir -type f -iname "*filename*" -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'
这将查找包含filename
在文件名中的所有文件/path/to/dir
,而不是对于找到的每个文件,搜索带有的行searchstring
并替换old
为new
。
尽管如果您想省略在文件名中查找带有filename
字符串的特定文件,而不是简单地执行以下操作:
find /path/to/dir -type f -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'
这将执行与上述相同的操作,但对/path/to/dir
.
另一种选择是将 perl 与 globstar 一起使用。
shopt -s globstar
在您的.bashrc
(或任何地方)启用允许**
glob 模式以递归方式匹配所有子目录和文件。
因此 usingperl -pXe 's/SEARCH/REPLACE/g' -i **
将递归替换SEARCH
为REPLACE
。
该-X
标志告诉 perl “禁用所有警告”——这意味着它不会抱怨目录。
globstar 还允许您执行一些操作,例如sed -i 's/SEARCH/REPLACE/g' **/*.ext
,如果您想在所有具有扩展名的子文件中SEARCH
替换为.REPLACE
.ext