将当前目录下所有文件中的一个字符串替换为另一个字符串

问题描述 投票:0回答:6

如何将当前目录下出现的每个字符串替换为另一个字符串?

示例: 我想将当前目录下每个文件中出现的所有

www.fubar.com
替换为
www.fubar.ftw.com

根据迄今为止的研究,我得出了

sed -i 's/www.fubar.com/www.fubar.ftw.com/g' *.php
string bash sed
6个回答
110
投票

您的方向是正确的,请使用

find
找到文件,然后使用
sed
编辑它们,例如:

find . -name '*.php' -exec sed -i -e 's/www.fubar.com/www.fubar.ftw.com/g' {} \;

注释

  • .
    表示当前目录 - 即在本例中,在当前目录及其下搜索。
  • 对于某些版本的
    sed
    ,您需要为
    -i
    选项指定扩展名,该选项用于备份文件。
  • -exec
    选项后面是要应用于找到的文件的命令,并以分号终止,分号必须转义,否则 shell 在传递给 find 之前将其消耗掉。

8
投票

比当前接受的解决方案更高效的*替代方案

grep "www.fubar.com" . -lr | xargs sed -i 's/www.fubar.com/www.fubar.ftw.com/g'

这避免了

find . -exec
方法的低效率,该方法不必要地对当前目录下的所有文件运行
sed
就地替换,无论它们是否包含您要查找的字符串,而是使用
grep -lr 
。这仅获取包含要替换的字符串的文件,然后您可以通过管道传输到
xargs sed -i
以仅对这些文件执行就地替换。


* :我使用

time
对我的方法与已接受的解决方案进行了粗略比较(适合我自己的用例);
find . -exec
风格的方法在我的机器上运行需要 3.624s,而我上面提出的解决方案需要 0.156s,所以对于我的用例来说大约快了 23 倍。


3
投票

使用 find、args 和 sed 的解决方案:

find . -name '*.php' -print0 | xargs -0 sed -i 's/www.fubar.com/www.fubar.ftw.com/g'

2
投票

一个纯粹的 bash 解决方案

#!/bin/bash
shopt -s nullglob
for file in *.php
do
    while read -r line
    do
       echo "${line/www.fubar.com/www.fubar.ftw.com}"
    done < "$file" > tempo && mv tempo "$file"

done

0
投票

当使用 ZSH 作为你的 shell 时,你可以这样做:

sed -i 's/www.fubar.com/www.fubar.ftw.com/g' **/*.php

0
投票

如果没有子文件夹,更容易记住的方法是

replace "www.fubar.com" "www.fubar.ftw.com" -- *

其中 * 也可以是文件列表 你需要这个别名才能像这样简单地工作:

 alias replace='function _replace() { from="$1"; to="$2"; shift 2; find . -type f \( -name "$@" \) -exec sed -i "s/${from}/${to}/g" {} +; }; _replace'

如果您有带点的隐藏文件,您可以使用

 将它们添加到 
*

shopt -s dotglob

如果您只有 一个深度的子文件夹,您可以使用

*/*
而不是
*

replace "www.fubar.com" "www.fubar.ftw.com" -- */*
© www.soinside.com 2019 - 2024. All rights reserved.