如何用Bash脚本递归替换文件夹文件中指定字符串为外部文件内容?
批量替换嵌套目录文本文件中的指定字符串
问题描述
- 有一个名为
Essays的文件夹,包含多层嵌套子目录和.txt文件。 - 仅部分文件内容包含字符串
[[RepeatedPara]]。 - 文件夹外的
specialPara.txt文件内容需要替换所有目标文件中的[[RepeatedPara]]字符串。 - 需要先将
Essays复制到新文件夹EssaysCopy,再执行替换操作,已编写脚本addPara.sh。
文件夹结构
. └── WorkingDir/ ├── addPara.sh ├── specialPara.txt ├── EssaysCopy └── Essays/ ├── file-01.txt ├── file-02.txt ├── file-03.txt ├── subDir-01/ │ ├── file-01-01.txt │ ├── file-01-02.txt │ └── subSubDir-01-01/ │ └── file-01-01.txt └── subDir-02/ ├── file-02-01.txt └── file-02-02.txt
现有脚本
#!/bin/sh cp -r Essays EssaysCopy cd EssaysCopy for FILE in $(find *.txt -type f); do sed -i -e '/RepeatedPara/{r ../specialPara.txt' -e 'd' -e '}' $FILE done
执行结果
脚本仅能替换EssaysCopy根目录下文件中的[[RepeatedPara]],无法处理嵌套子目录中的文件。
测试用目录与文件生成脚本
#!/bin/sh mkdir Essays cd Essays for i in {1..3} do mkdir subDir-$i cd subDir-$i for j in {1..2} do mkdir subDir-$j cd subDir-$j for k in {1..2} do echo "Some Content at the begining" > file-$i-$j-$k.txt echo "[[RepeatedPara]]" >> file-$i-$j-$k.txt echo "Some Content at the End" >> file-$i-$j-$k.txt done cd .. done for l in {1..2} do echo "Some Content at the begining" > file-$i-$l.txt echo "[[RepeatedPara]]" >> file-$i-$l.txt echo "Some Content at the End" >> file-$i-$l.txt done cd .. done for m in {1..2} do echo "Some Content at the begining" > file-$m.txt echo "[[RepeatedPara]]" >> file-$m.txt echo "Some Content at the End" >> file-$m.txt done cd ..
修复方案
问题根源
find *.txt -type f仅查找当前目录下的.txt文件,不会递归遍历子目录,导致嵌套目录中的文件未被处理。- 正则表达式中的
[[是特殊元字符,未转义可能导致匹配不准确。 - 使用
for FILE in $(find ...)处理含空格的文件名会出现错误。
修复后的脚本(方式一:while read 处理)
#!/bin/sh # 复制原目录到新文件夹 cp -r Essays EssaysCopy # 进入目标目录,失败则退出 cd EssaysCopy || exit 1 # 递归查找所有txt文件,逐行处理文件名(兼容含空格的文件名) find . -name "*.txt" -type f | while read -r FILE; do # 转义正则特殊字符,精准匹配[[RepeatedPara]],替换为specialPara.txt内容 sed -i -e '/\[\[RepeatedPara\]\]/{r ../specialPara.txt' -e 'd' -e '}' "$FILE" done
修复后的脚本(方式二:find -exec 简化版)
#!/bin/sh cp -r Essays EssaysCopy cd EssaysCopy || exit 1 # 直接用find的-exec参数执行sed,无需循环 find . -name "*.txt" -type f -exec sed -i -e '/\[\[RepeatedPara\]\]/{r ../specialPara.txt' -e 'd' -e '}' {} \;
说明
find . -name "*.txt" -type f:从当前目录(.)开始递归查找所有.txt类型文件。\[\[RepeatedPara\]\]:转义正则特殊字符,确保仅匹配目标字符串[[RepeatedPara]]。while read -r FILE:安全处理含空格、特殊字符的文件名;find -exec则直接将文件路径传递给sed,同样避免文件名问题。
内容的提问来源于stack exchange,提问作者YourPalNurav
相关产品推荐
相关产品推荐

