我需要一个目录中的所有文件和子目录中的递归搜索指定的字符串并替换该字符串用另一个字符串。
我知道的命令找出它可能是这样的:
grep 'string_to_find' -r ./*
但是,我怎么能更换的每个实例string_to_find
用另一个字符串?
我需要一个目录中的所有文件和子目录中的递归搜索指定的字符串并替换该字符串用另一个字符串。
我知道的命令找出它可能是这样的:
grep 'string_to_find' -r ./*
但是,我怎么能更换的每个实例string_to_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'
你甚至可以遵循这样的..
例
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
这将搜索相对于当前目录下的所有文件的字符串“ 窗口 ”,并在每个文件中的字符串每次出现'Linux的替换“ 窗口 ”。
这最适合我的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
其它解决方案混合正则表达式的语法。 使用Perl / PCRE模式两种搜索和替换,避免加工的每一个文件,这个工作得很好:
grep -rlZP 'match1' | xargs -0r perl -pi -e 's/match2/replace/g;'
其中match1
和match2
通常是相同的,但match1
可以被简化以去除更先进的功能,是仅相关的取代,例如捕获组。
翻译:递归grep和列表匹配的文件,通过NUL分开,以保护在文件名中的任何特殊字符,那场比赛这个PCRE模式,然后通过管道的文件名,其期待一个空分隔的列表xargs的,但如果不会做任何事情,名字被接收,并获得Perl来重写每一个文件,替换那里找到匹配行。
加入I
的选择,以grep
忽略二进制文件,太。
通常不使用grep,而是与sed -i 's/string_to_find/another_string/g'
或perl -i.bak -pe 's/string_to_find/another_string/g'
使用时要非常小心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
另一种选择是只用perl与globstar。
启用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
。