MacOS下如何用Bash实现VSCode式的全局搜索替换?
解决MacOS下sed批量替换文件内容(含子目录)的问题
你的问题出在*会匹配当前目录下的所有对象(包括文件夹b),而sed -i只能编辑普通文件,无法处理目录,因此报错。以下是几种可行的解决方法:
方法一:用find命令递归处理文件
这是最可靠的跨平台方案,能精准定位所有需要修改的普通文件:
# 仅处理当前目录及子目录下的.txt文件,保留备份(后缀.bak) find . -type f -name "*.txt" -exec sed -i '.bak' 's/hello/goodbye/g' {} + # 如果不需要备份文件,把-i '.bak'改成-i '' find . -type f -name "*.txt" -exec sed -i '' 's/hello/goodbye/g' {} + # 若要处理所有类型的普通文件,去掉-name "*.txt"即可 find . -type f -exec sed -i '' 's/hello/goodbye/g' {} +
参数说明:
.表示从当前目录开始递归查找-type f只筛选普通文件,排除目录-exec ... {} +将找到的文件批量传给sed执行,比{} \;效率更高
方法二:用globstar匹配子目录(需bash 4.0+)
Mac默认的bash版本是3.2,不支持**通配符,需要先开启globstar选项:
# 开启globstar(仅当前会话有效,重启终端后需重新执行) shopt -s globstar # 替换当前目录及所有子目录下的.txt文件内容 sed -i '' 's/hello/goodbye/g' **/*.txt # 替换所有类型文件的话用: sed -i '' 's/hello/goodbye/g' **
注意事项
- MacOS的
sed是BSD版本,和Linux的GNU sed语法有差异:-i后面必须指定备份后缀(即使是空的),空后缀-i ''表示不生成备份文件。 - 如果执行
shopt -s globstar报错,说明你的bash版本过低,可以升级bash(比如用Homebrew安装bash),或者直接用方法一的find方案。
内容的提问来源于stack exchange,提问作者gkeenley
相关产品推荐
相关产品推荐

