我需要在目录中的所有文件和子目录中递归搜索指定的字符串,并将该字符串替换为另一个字符串。
我知道找到它的命令可能像这样:
grep 'string_to_find' -r ./*
但是,如何string_to_find用另一个字符串替换每个的实例?
sed -i 's/.*substring.*/replace/'
sed -i 's/\(.*\)substring\(.*\)/\1replace\2/'
我需要在目录中的所有文件和子目录中递归搜索指定的字符串,并将该字符串替换为另一个字符串。
我知道找到它的命令可能像这样:
grep 'string_to_find' -r ./*
但是,如何string_to_find用另一个字符串替换每个的实例?
sed -i 's/.*substring.*/replace/'
sed -i 's/\(.*\)substring\(.*\)/\1replace\2/'
Answers:
另一种选择是使用查找,然后将其传递给sed。
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;
-i需要参数的正确扩展字符串。例如,find /path/to/files -type f -exec sed -i "" "s/oldstring/new string/g" {} \;无论如何,提供空字符串仍然会创建备份文件,与手册中所述的不同……
-i ""为OS X 添加了。
CRLF为LF。
我得到了答案。
grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
grep然后一次sed。使用find方法更有效,但是您提到的此方法确实有效。
sed -i 's/str1/str2/g'到sed -i "" 's/str1/str2/g'这个工作。
grep将浏览所有文件,sed仅扫描与匹配的文件grep。使用find其他答案中的方法,find首先列出所有文件,然后sed扫描该目录中的所有文件。所以这种方法并不一定要慢,这取决于有多少场比赛有和之间的搜索速度的差异sed,grep和find。
您甚至可以这样做:
例
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
这将在相对于当前目录的所有文件中搜索字符串“ windows ”,并在每个文件中每次出现的字符串中将“ windows ” 替换为“ linux ”。
grep仅当存在不应修改的文件时,此选项才有用。sed在所有文件上运行将更新文件的修改日期,但如果没有匹配项,则使内容保持不变。
-i我相信sed每变化倒是文件的文件时,即使内容不变,sed也将转换行结束我不使用sed在Windows中一个Git回购,因为所有CRLF的改变LF。
这在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
sort -u偶数部分?您希望在什么情况下grep -rl产生两次相同的文件名?
其他解决方案混合了正则表达式语法。使用Perl / PCRE模式为两种搜索和替换,只有工艺匹配的文件,这个作品非常好:
grep -rlZPi 'match1' | xargs -0r perl -pi -e 's/match2/replace/gi;'
其中match1和match2通常相同,但match1可以简化以删除仅与替换有关的更高级的功能,例如捕获组。
翻译:grep递归地列出与该PCRE模式匹配的文件,并用nul分隔以保护文件名中的任何特殊字符,然后通过管道将那些xargs期望以nul分隔的列表的文件名传递到文件名,但是如果没有收到名称,则不会执行任何操作,并perl找到找到匹配项的替代行。
将I开关添加到grep以忽略二进制文件。为区分大小写匹配,则删除i从开关grep,并且i连接到替换表达式标志,但不是在i上开关perl本身。
find不会搜索文件内容,关键是只处理匹配的文件而无需编写Perl程序。
要非常小心使用时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(或任意位置)允许**全局模式以递归方式匹配所有子目录和文件。
因此,使用perl -pXe 's/SEARCH/REPLACE/g' -i **将递归替换SEARCH用REPLACE。
该-X标志告诉perl“禁用所有警告”-这意味着它不会抱怨目录。
该globstar还允许你做这样的事情sed -i 's/SEARCH/REPLACE/g' **/*.ext,如果你想更换SEARCH同REPLACE在扩展所有子文件.ext。
grep和sed。