我使用以下命令以递归方式搜索特定字符串的目录,并将其替换为另一个:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g'
这没关系。唯一的问题是如果字符串不存在则sed
失败,因为它没有得到任何参数。这对我来说是一个问题,因为我使用ANT自动运行它,并且由于sed
失败,构建失败。
如果找不到字符串,有没有办法使其防止失败?
我对我可以使用的一行简单解决方案感兴趣(不一定是grep
或sed
,而是使用这些常见的unix命令。)
答案 0 :(得分:69)
您可以将find
和-exec
直接用于sed
,而不是首先使用oldstr
找到grep
。效率可能稍低,但这可能并不重要。这样,对sed
列出的所有文件执行find
替换,但如果oldstr
不存在,则显然不会对其进行操作。
find /path -type f -exec sed -i 's/oldstr/newstr/g' {} \;
答案 1 :(得分:9)
你的解决方案没问题。只能这样试试:
files=$(grep -rl oldstr path) && echo $files | xargs sed....
所以只有当grep返回xargs
时执行0
,例如在某些文件中找到字符串时。
答案 2 :(得分:7)
标准xargs
无法做到这一点;你最好不要像其他人建议的那样使用find -exec
,或者将sed
包装在一个脚本中,如果没有参数则不会做任何事情。 GNU xargs
具有--no-run-if-empty
选项,而BSD / OS X xargs
具有-L
选项,看起来它应该做类似的事情。
答案 3 :(得分:7)
我采取了弗拉德的想法并改变了一点。而不是
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
哪个收益
sed: couldn't edit /dev/null: not a regular file
我正在与远程服务器建立3个不同的连接
touch deleteme
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' ./deleteme
rm deleteme
虽然这不那么优雅,并且需要2个与服务器的连接(也许有一种方法可以在一行中完成),它也可以有效地完成工作
答案 4 :(得分:4)
我认为如果不使用-exec
,您只需提供/dev/null
作为至少一个参数,以防无法找到:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
答案 5 :(得分:1)
我的用例是我想要替换
foo:/Drive_Letter
foo:/bar/baz/xyz
find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'
在我的情况下,我能够使用以下代码完成它。
我在大量文件的同一目录位置。
{{1}}
希望有所帮助。
答案 6 :(得分:0)
不确定这是否有帮助,但是您可以将其用于远程服务器,如下面的示例
ssh example.server.com“找到/ DIR_NAME-类型f-名称” FILES_LOOKING_FOR“ -exec sed -i's / LOOKINGFOR / withThisString / g'{};”
将example.server.com替换为服务器 将DIR_NAME替换为您的目录/文件位置 用您要查找的文件替换FILES_LOOKING_FOR 用您要寻找的代替LOOKINGFOR 用要替换的文件替换thisString
答案 7 :(得分:-1)
如果要替换固定字符串或某些模式,我还想添加bash内置模式字符串替换变量替换构造。我不是自己描述,而是引用bash手册中的部分:
${parameter/pattern/string}
扩展模式以生成与路径名一样的模式 扩张。 参数已展开, pattern 与其值的最长匹配将替换为 string 。如果模式 以
/
开头, pattern 的所有匹配项都替换为字符串。 通常只替换第一场比赛。如果 pattern 开始 使用#
时,它必须在扩展值的开头匹配 参数。如果 pattern 以%
开头,则必须在结尾处匹配 参数的扩展值。如果 string 为null,则匹配 删除模式,并且可以省略模式之后的/
。如果参数为@
或*
,则替换操作为 依次应用于每个位置参数,并进行扩展 是结果列表。如果参数是使用@
或*
下标的数组变量,则替换操作将应用于 依次是数组的每个成员,而扩展是 结果清单。