Bash 如何从命令行执行递归查找和替换?

Bash 如何从命令行执行递归查找和替换?,bash,shell,readline,Bash,Shell,Readline,是否有一种简单的方法可以递归搜索目录层次结构中的所有文件以查找某个术语(例如,端口),并用另一个术语替换该术语的所有匹配项(例如,端口查找) 我在中尝试了这些建议,但它们只适用于单个文件。试试这个 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'

是否有一种简单的方法可以递归搜索目录层次结构中的所有文件以查找某个术语(例如,
端口
),并用另一个术语替换该术语的所有匹配项(例如,
端口查找

我在中尝试了这些建议,但它们只适用于单个文件。

试试这个

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' 

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

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

grep -r -l "port" | xargs -r -d'\n' sed -i 's/port/port-lookup/g'
我建议您在Unix&Linux exchange上阅读有关此主题的全面介绍


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

上述命令在文件中重复搜索并将纯文本
端口
替换为
端口查找

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

有关查找和替换文件或管道的更多用法,请参见我打开的项目(
msr.exe
/
msr.gcc*
/
msr.cygwin
位于
tools
目录中)。内置用法和exmaples只运行exe。像这样的文档。

这是一个整洁的Bash 4功能,我需要记下来!它还内置于zsh中,这是我第一次使用它的地方。当我登录到bash 3时,我总是有点失望,这不起作用。对
grep
的初始调用做得很好,除了其他好处外,它可以防止更新文件mod和访问时间,如果单独使用
sed-I
,所有文件都会更新。虽然您可以使用
查找-execdir sed-i…
要搜索所有文件的
端口
并进行更改,它将更新所有文件的文件时间,无论是否进行了更改。回答也很好,但缺点是更新所有文件修改时间,不管是否找到/更新了
port
。grep-rl'port'/search\u在Mac上的这个目录中| xargs sed-i's/port/port offset/g',您会发现在
-i
之后不添加参数将导致不需要的文件带有-e后缀。要删除这些,请运行
find./-typef-exec sed-i'-e's/port/port lookup/g'{}\取而代之。谢谢大家!所有的建议都很有效。我选择了基于David C.Rankin提到的好处的
grep
答案。
grep -r -l "port" | xargs -r -d'\n' sed -i 's/port/port-lookup/g'