【问题标题】:How to do a recursive find and replace from the command line?如何从命令行进行递归查找和替换?
【发布时间】:2018-03-10 23:45:10
【问题描述】:

有没有一种简单的方法可以递归地在目录层次结构中的所有文件中搜索一个术语(例如port)并将该术语的所有出现替换为另一个(例如port-lookup)。

我已经尝试了this post 中的建议,但它们仅适用于单个文件。

【问题讨论】:

  • 谢谢大家!所有的建议都很好。根据 David C. Rankin 提到的好处,我选择了 grep 答案。

标签: bash shell readline


【解决方案1】:

实现此目的的最简单(并且可以说是最纯粹和直观)的方法是执行递归文件 grep,然后将这些文件结果通过管道传输到 sed(通过 xargs)以处理就地替换。

grep -r -l "port" | xargs -r -d'\n' sed -i 's/port/port-lookup/g'

有一个关于这个主题的综合community wiki answer,我建议在 Unix 和 Linux 交流中阅读。

【讨论】:

  • grep 的初始调用做得很好,除其他好处外,它还可以防止更新文件模式和访问时间,如果单独使用sed -i,所有文件都会更新。虽然您可以使用 find ... -execdir sed -i.... 在所有文件中搜索 port 并进行更改,但它会更新所有文件时间,无论是否进行任何更改。
【解决方案2】:

试试这个

find ./ -type f -exec sed -i -e 's/port/port-lookup/g' {} \;

如果您不想更改文件修改时间

grep -rl 'port' /search_in_this_dir | xargs sed -i 's/port/port-offset/g' 

【讨论】:

  • 答案也不错,但无论是否找到/更新了port,都会更新所有文件修改时间。
  • grep -rl 'port' /search_in_this_dir | xargs sed -i 's/port/port-offset/g'
  • 在 Mac 上,您会发现在 -i 之后不添加参数会导致不需要的文件带有 -e 后缀。要删除这些,请改为运行 find ./ -type f -exec sed -i '' -e 's/port/port-lookup/g' {} \;
【解决方案3】:

如果您有最新版本的 bash (>4)

shopt -s globstar
sed -i 's/port/port-lookup/g' **/*

【讨论】:

  • 这是一个简洁的 Bash 4 功能,我需要记下!
  • 它也内置在 zsh 中,这是我首先开始使用它的地方。当我登录到 bash 3 时,我总是有点失望,但这不起作用。
【解决方案4】:

只有 1 个命令行:msr -rp dir1,dir2,file1,fileN -x port -o port-lookup -R

上述命令在文件中反复搜索并将纯文本port替换为port-lookup

  • 如果您想预览替换结果,请删除-R
  • 如果要预览和汇总文件列表和计数/分发,请添加-l
  • 如果要备份更改的文件,请添加-K,例如-K -R-RK
  • 忽略大小写添加-i 喜欢-i -x-ix
  • 如果你想使用C++/C#/Java/Scala Regex语法,使用-t而不是-x
  • 过滤文件名like:包括-f "\.(xml|java|cpp)$",排除--nf "\.(so|a|lib|dll|obj)$"
  • 过滤目录名称如:包括-d "src",排除--nd "^(target|\.git)$"
  • 过滤文件大小范围如:--s1 1/--s1 1B 和/或--s2 1.20MB
  • 过滤文件上次写入时间范围如:--w1 2017-08-01 和/或--w2 "2017-08-12 11:20:30"

更多关于查找和替换文件或管道的用法见我打开的项目https://github.com/qualiu/msrmsr.exe/msr.gcc*/msr.cygwintools目录中)。内置用法和示例只需运行 exe。 performance comparision with findstr and grep 之类的文档。

【讨论】:

    猜你喜欢
    • 2018-06-25
    • 2011-07-27
    • 2017-03-21
    • 1970-01-01
    • 2013-02-09
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多