我如何查找并替换每次出现的:

subdomainA.example.com

具有

subdomainB.example.com

递归地在/home/www/目录树下的每个文本文件中?


当前回答

对我来说,最容易记住的解决方案是https://stackoverflow.com/a/2113224/565525即:

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

注意:-i“”解决了OSX问题sed:1:“…”:命令代码无效。

注意:如果要处理的文件太多,参数列表会太长。解决方法-使用上述find-exec或xargs解决方案。

其他回答

我只使用上衣:

find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose  replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" \
replace "check(<b args>)" with "__Check(<args>)" 

用更简单的fd(1)/fdfind=替换find(1)https://github.com/sharkdp/fd:

fdfind . --type f --exec sed -i "s/original_string/new_string/g"

寻址fd(1)iconsistent pkg和cmd名称

在macOS自制软件上:pkg和cmd=fd在Ubuntu 20.04上:pkg=fd find,cmd=fdfind

我在macOS上创建了一个别名fdfind='fd',以实现一致的cmd命名(在我的macOS和Linux平台之间)。

有关这一点的更多信息,请访问https://github.com/sharkdp/fd/issues/1009.

更多细节和附加功能

# bash examples:

1='original_string'
2='new______string'

# for this (the original-poster's) question:
1='subdomainA.example.com'
2='subdomainB.example.com'

# 'fdfind' (on at least Ubuntu 20.04) = 'fd' = https://github.com/sharkdp/fd

fdfind . --type f --exec sed -i "s/$1/$2/g"

# Here's a slightly-more-complex example that
# a. excludes (-E) .git/ and archive/ dirs, and
# b. performs a word-boundary search on the original_string (\<$1\>):
fdfind . -E .git/ -E archive/ --type f --exec sed -i "s/\<$1\>/$2/g"

甚至更高级:从第三个($3)命令行参数控制单词边界(第三个参数=noword表示无边界,leftword表示仅左侧单词边界,rightword表示仅右侧边界):

#!/usr/bin/env bash

#
# replace-tree.bash
#

# 'fdfind' (on at least Ubuntu 20.04) = 'fd' = https://github.com/sharkdp/fd

if [ $# -lt 2 ]; then
  echo "$0: Please provide at least 2 arguments."
  exit 1
fi

original="\<$1\>"

if   [ "$3" = "noword" ];    then
  original="$1"
elif [ "$3" = "leftword" ];  then
  original="\<$1"
elif [ "$3" = "rightword" ]; then
  original="$1\>"
fi

fdfind . --type f --exec sed -i "s/$original/$2/g"

示例用法:

$ replace-tree.bash original_string new_string leftword
$

最简单的替换方式(所有文件、目录、递归)

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

注意:有时您可能需要忽略一些隐藏文件,例如.git,您可以使用上面的命令。

如果要包含隐藏文件,请使用,

find . -type f  -exec sed -i 's/foo/bar/g' {} +

在这两种情况下,字符串foo将被替换为新的字符串栏

如果您不介意将vim与grep或find工具一起使用,您可以在以下链接中跟进用户Gert给出的答案-->如何在大文件夹层次结构中进行文本替换?。

交易如下:

递归地对要在某个路径中替换的字符串执行grep,并只获取匹配文件的完整路径。(这将是$(grep”字符串“”路径名“-Rl”)。(可选)如果您想对集中目录上的这些文件进行预备份,您也可以使用以下命令:cp-iv$(grep‘string‘‘pathname‘-Rl)‘集中目录路径名‘之后,您可以在vim中按照与给定链接上提供的方案类似的方案随意编辑/替换::bufdo%s#string#replacement#gc | update

如果您可以访问节点,可以执行npm安装-grexreplace,然后

rexreplace 'subdomainA.example.com' 'subdomainB.example.com' /home/www/**/*.*