如何处理文件夹结构中与模式匹配的所有文件? [复制]
Posted
技术标签:
【中文标题】如何处理文件夹结构中与模式匹配的所有文件? [复制]【英文标题】:How to process all files from a folder structure that match a pattern? [duplicate] 【发布时间】:2019-02-19 02:45:43 【问题描述】:我正在尝试编写一个 Bash 脚本,该脚本将处理文件夹结构中与模式匹配的所有文件(例如 *.properties
或 *.conf
)。我的用例是在无数应用程序配置文件中将服务器名称 (server-xx
) 替换为另一个服务器名称 (server-yy
)。
基本上,就是从根目录开始查找文件夹结构中的所有文件,并对所有文件应用相同的处理。
我正在慢慢构建脚本,它变得比我最初的意图暗示的要困难得多。它有四个参数:
根路径 文件模式 要替换的字符串 替换字符串这是它的当前状态:
# The echoing of usage notes is omitted here.
nbArgs=$#
if [[ $nbArgs -ne 4 ]]
then
echo "Four parameters are required."
else
echo "Running..."
filelist=`find $1 -name "$2" 2> /dev/null`
printf "Files: $filelist"
echo
while read filename ; do
if [[ -e $filename ]]; then
line="sed -i 's/$3/$4/g' $filename"
echo "Executing $line"
fi
done <<< "$filelist"
echo "Done. Exiting."
fi
示例运行:./adapt-properties-files.sh /mnt/c/Users/avoglozin/Apps/test-adapt/ "*.properties" server-xx.domain.com server-yy.domain.com
此脚本的目标“生产”环境是 Ubuntu 专用机器,但我使用 Windows 10 下的 Ubuntu Bash 进行开发。
问题是当我运行find
命令时,例如find ./test-adapt/ -name "*.properties" 2> /dev/null
在 shell 中,我得到了终端中显示的正确文件列表。但是,当我运行脚本时,filelist
变量只显示一个文件。一些可能显而易见的知识正在回避我。
【问题讨论】:
文件是否有类似这样的 hashbang-line:#! /bin/sh
或 #! /bin/bash
?如果是前者,请尝试后者。
您的脚本包含大量常见错误。我尝试为最重要的添加重复项,但简而言之,您需要像 find "$1" -name "$2" -exec sed -i "s/$3/$4/" +
这样的东西,您应该注意引用并可能添加一些装饰以应对正则表达式转义等。尝试在存储中间结果的同时零碎做事在简单的标量变量中会产生大量的并发症;另见mywiki.wooledge.org/BashFAQ/050。最后,请查看shellcheck.net 以自动诊断其中许多错误。
mywiki.wooledge.org/UsingFind 也是一个很好的资源,它指出了许多棘手的极端情况。
@OlliK 是的,该文件包含一个 bash hashbang。
@tripleee 确实有很多并发症,但是在尝试调试问题时添加了一些中间变量。谢谢。
【参考方案1】:
在我看来,这可以缩短为
find "$1" -name "$2" -type f -exec sed -i -e "s/$3/$4/g" +
【讨论】:
如果find
返回包含空格或文字shell 元字符的文件名,这将失败。这是常见的常见问题解答。
检查这个mywiki.wooledge.org/BashFAQ/001。您的解决方案在大多数情况下都有效,但在 SO 上,最好使用始终有效的解决方案来回答(披露,几个月前我学到了完全相同的事情 :-)以上是关于如何处理文件夹结构中与模式匹配的所有文件? [复制]的主要内容,如果未能解决你的问题,请参考以下文章