使用 grep 和 sed 查找和替换字符串
我使用以下命令递归地搜索目录中的特定字符串并将其替换为另一个字符串:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g'
这可以正常工作。唯一的问题是,如果字符串不存在,则 sed 会失败,因为它没有获取任何参数。这对我来说是一个问题,因为我使用 ANT 自动运行它,并且由于 sed 失败而构建失败。
有没有办法在找不到字符串的情况下防止失败?
我对可以使用的一行简单解决方案感兴趣(不一定使用 grep
或 sed
但使用像这样的常见 UNIX 命令)。
I am using the following to search a directory recursively for specific string and replace it with another:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g'
This works okay. The only problem is that if the string doesn't exist then sed
fails because it doesn't get any arguments. This is a problem for me since i'm running this automatically with ANT and the build fails since sed
fails.
Is there a way to make it fail-proof in case the string is not found?
I'm interested in a one line simple solution I can use (not necessarily with grep
or sed
but with common unix commands like these).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我采纳了弗拉德的想法并做了一些改变。 而不是在其中
进行生成,
我正在与远程服务器建立 3 个不同的连接,
尽管这不太优雅并且需要与服务器的另外 2 个连接(也许有一种方法可以在一行中完成所有操作),但它也可以高效地完成工作
I have taken Vlad's idea and changed it a little bit. Instead of
Which yields
I'm doing in 3 different connections to the remote server
Although this is less elegant and requires 2 more connections to the server (maybe there's a way to do it all in one line) it does the job efficiently as well
标准的 xargs 没有好的方法来做到这一点;您最好按照其他人的建议使用
find -exec
,或者将sed
包装在一个脚本中,如果没有参数,该脚本将不执行任何操作。 GNUxargs
具有--no-run-if-empty
选项,BSD / OS Xxargs
具有-L< /code> 选项看起来应该做类似的事情。
Standard
xargs
has no good way to do it; you're better off usingfind -exec
as someone else suggested, or wrap thesed
in a script which does nothing if there are no arguments. GNUxargs
has the--no-run-if-empty
option, and BSD / OS Xxargs
has the-L
option which looks like it should do something similar.我认为,在不使用
-exec
的情况下,您可以简单地提供/dev/null
作为至少一个参数,以防找不到任何内容:I think that without using
-exec
you can simply provide/dev/null
as at least one argument in case nothing is found:我的用例是我想更换
foo:/Drive_Letter
与foo:/bar/baz/xyz
就我而言,我可以使用以下代码来完成此操作。
我位于有大量文件的同一目录位置。
希望有帮助。
My use case was I wanted to replace
foo:/Drive_Letter
withfoo:/bar/baz/xyz
In my case I was able to do it with the following code.
I was in the same directory location where there were bulk of files.
hope that helped.
不确定这是否有帮助,但您可以将其与远程服务器一起使用,如下例所示
ssh example.server.com "find /DIR_NAME -type f -name "FILES_LOOKING_FOR" -exec sed -i 's/LOOKINGFOR/withThisString/ g'{};"
将 example.server.com 替换为您的服务器
将 DIR_NAME 替换为您的目录/文件位置
将 FILES_LOOKING_FOR 替换为您要查找的文件
将 LOOKINGFOR 替换为您要查找的内容
将 withThisString 替换为您想要在文件中替换的内容
Not sure if this will be helpful but you can use this with a remote server like the example below
ssh example.server.com "find /DIR_NAME -type f -name "FILES_LOOKING_FOR" -exec sed -i 's/LOOKINGFOR/withThisString/g' {} ;"
replace the example.server.com with your server
replace DIR_NAME with your directory/file locations
replace FILES_LOOKING_FOR with files you are looking for
replace LOOKINGFOR with what you are looking for
replace withThisString with what your want to be replaced in the file
如果要替换固定字符串或某些模式,我还想添加 bash 内置模式字符串替换变量替换构造。我没有自己描述它,而是引用 bash 手册中的部分:
If you are to replace a fixed string or some pattern, I would also like to add the bash builtin pattern string replacement variable substitution construct. Instead of describing it myself, I am quoting the section from the bash manual:
您可以直接在
sed
中使用find
和-exec
,而不是先使用grep
定位oldstr
代码>.它的效率可能会低一些,但这可能并不重要。这样,sed
替换就会在find
列出的所有文件上执行,但如果oldstr
不存在,它显然不会对其进行操作它。You can use
find
and-exec
directly intosed
rather than first locatingoldstr
withgrep
. It's maybe a bit less efficient, but that might not be important. This way, thesed
replacement is executed over all files listed byfind
, but ifoldstr
isn't there it obviously won't operate on it.你的解决方案没问题。仅以这种方式尝试:
因此仅当 grep 返回
0
时才执行xargs
,例如在某些文件中找到该字符串时。Your solution is ok. only try it in this way:
so execute the
xargs
only when grep return0
, e.g. when found the string in some files.