【问题标题】:Find and replace using xargs sed - can I save the results to a file?使用 xargs sed 查找和替换 - 我可以将结果保存到文件中吗?
【发布时间】:2012-02-23 14:26:09
【问题描述】:

我用 'bar' 替换所有 'foo' 实例的代码:

find . -type f |
xargs grep 'foo' -l |
xargs sed -i 's|foo|bar|g'

我想将修改后的文件列表保存到文本文档中。可能吗?

编辑:

这是对我有用的最终代码:

find . -type f -print0 |
xargs -0 grep 'foo' -l |
tee result.txt |
xargs -0 sed -i 's|foo|bar|g'

不确定这是否是最快的方法,但对于几千个文件,这种方法与其他建议方法的速度差异可能非常小。

【问题讨论】:

  • 你为什么不用一个小子集来测试时间 - 不是太小,但也许可以运行一分钟?如果您的数据不是非典型的,我不会期望太大的差异。但是您的代码会因文件名包含空格、制表符、换行符等而失败。您确定您的文件不包含此类内容吗?
  • 在您的 cmets 之后,我使用 print0-0 修改了上面的代码
  • 是的,但是使用 xargs 和类似的批处理方法肯定是一个好习惯,因为当您的参数大小超过命令行限制时,名称中有空格或非典型字符 (print0) 或存在风险许多进程(exec)被分叉而不是批处理。

标签: replace sed find grep xargs


【解决方案1】:

看起来像xargs 的无用用法,经常与find 结合使用。

find . -type f -exec grep 'foo' -l {} ";" -exec sed -i 's|foo|bar|g' {} ";" -ls > file.lst

小心使用它,因为我没有测试它。我不确定您是否喜欢更改文件名列表或文件内容。由于您使用grepsed 进行搜索,我认为仅使用sed 就足够了:

find . -type f -exec sed -i 's|foo|bar|g' {} ";" -ls > file.lst

【讨论】:

  • 我只希望修改内容,而不是文件名。唯一应该修改的文件是那些包含字符串的文件。
  • 我应该补充一点,有成千上万的文件正在被搜索和修改。 exec 在这方面比 xargs 好吗?
  • xargs 是一个额外的过程,你不能用它做很多事情,用 -exec 做不到的事情更容易。 Find 知道结果的哪一部分是文件名,它从哪里开始和在哪里结束。要安全地使用 xargs,您必须清除文件名中的空格、换行符和其他丑陋的内容(使用 -print0 可以做到这一点,但会使命令更大)。 (但我必须在 exec 参数中添加 2 或 3 个“;”。如果您的限制因素是我怀疑的 HDD 速度,那么使用并行调用没有多大用处。但即使使用 + 而不是并行调用也可以“;”。
  • 大约数千个文件:如果第一个“foo”接近文件末尾,则读取两次,一次由 grep 读取,一次由 sed 读取。如果没有“foo”,则在您的示例中完全由 grep 读取,在我的示例中完全由 sed 读取。如果“foo”接近开头,您会使用 grep 读取它,并且完全使用 sed。通过我的方法,只能完全使用 sed。为什么 sed 应该比 grep 慢?
  • 好的,我认为你是对的。但是,我认为您的第二个示例将导致每个文件的修改日期发生变化,无论它是否包含“foo”。
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 2012-02-14
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 2017-09-12
相关资源
最近更新 更多