【发布时间】:2018-03-10 23:45:10
【问题描述】:
有没有一种简单的方法可以递归地在目录层次结构中的所有文件中搜索一个术语(例如port)并将该术语的所有出现替换为另一个(例如port-lookup)。
我已经尝试了this post 中的建议,但它们仅适用于单个文件。
【问题讨论】:
-
谢谢大家!所有的建议都很好。根据 David C. Rankin 提到的好处,我选择了
grep答案。
有没有一种简单的方法可以递归地在目录层次结构中的所有文件中搜索一个术语(例如port)并将该术语的所有出现替换为另一个(例如port-lookup)。
我已经尝试了this post 中的建议,但它们仅适用于单个文件。
【问题讨论】:
grep 答案。
实现此目的的最简单(并且可以说是最纯粹和直观)的方法是执行递归文件 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 并进行更改,但它会更新所有文件时间,无论是否进行任何更改。
试试这个
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,都会更新所有文件修改时间。
-i 之后不添加参数会导致不需要的文件带有 -e 后缀。要删除这些,请改为运行 find ./ -type f -exec sed -i '' -e 's/port/port-lookup/g' {} \;。
如果您有最新版本的 bash (>4)
shopt -s globstar
sed -i 's/port/port-lookup/g' **/*
【讨论】:
只有 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。-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/msr(msr.exe/msr.gcc*/msr.cygwin在tools目录中)。内置用法和示例只需运行 exe。 performance comparision with findstr and grep 之类的文档。
【讨论】: