如何使用 grep 进行搜索和替换
- 2024-10-22 08:28:00
- admin 原创
- 78
问题描述:
我需要在目录内的所有文件和子目录中递归搜索指定的字符串,并用另一个字符串替换该字符串。
我知道找到它的命令可能看起来像这样:
grep 'string_to_find' -r ./*
string_to_find
但是我怎样才能用另一个字符串替换每个实例呢?
解决方案 1:
另一个选择是使用 find,然后将其传递给 sed。
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} ;
解决方案 2:
我得到了答案。
grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
解决方案 3:
你甚至可以这样做:
例子
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
这将在相对于当前目录的所有文件中搜索字符串“ windows ”,并将每个文件中每次出现的字符串“ windows ”替换为“ linux ”。
解决方案 4:
这对我来说在 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
解决方案 5:
通常不使用 grep,而是使用sed -i 's/string_to_find/another_string/g'
or perl -i.bak -pe 's/string_to_find/another_string/g'
。
解决方案 6:
其他解决方案混合了正则表达式语法。要使用 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
perlI
grep`
解决方案 7:
find
在 git repo 中使用时要非常小心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
解决方案 8:
以下是我要做的事情:
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
。
解决方案 9:
现代的 rust 工具可以用来完成这项工作。例如,要在所有(非忽略)文件中分别用“newstring”和“newString”替换“oldstring”和“oldString”,您可以:
使用fd和sd
fd -tf -x sd 'old([Ss]tring)' 'new$1' {}
使用ned
ned -R -p 'old([Ss]tring)' -r 'new$1' .
使用ruplacer
ruplacer --go 'old([Ss]tring)' 'new$1' .
忽略的文件
要包含忽略的文件.gitignore
和隐藏的文件,您必须指定它:
用于,
-IH
fd
用于。
--ignored --hidden
ruplacer
解决方案 10:
另一个选择是仅使用带有 globstar 的 perl。
shopt -s globstar
在您的.bashrc
(或任何地方)启用允许**
glob 模式递归匹配所有子目录和文件。
因此使用perl -pXe 's/SEARCH/REPLACE/g' -i **
将递归地SEARCH
替换REPLACE
。
该-X
标志告诉 perl“禁用所有警告” - 这意味着它不会抱怨目录。
globstar 还允许您执行一些操作,例如如果您想在所有子文件中用sed -i 's/SEARCH/REPLACE/g' **/*.ext
替换扩展名。SEARCH
`REPLACE`.ext
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件