运行部署脚本,在将文件上传到 S3 存储桶之前删除文件的 .html 部分。目前使用以下内容:
cd out/
for file in `ls -l *.html`; do
newname=`echo $file|sed 's/\.html$//g'`
mv $file $newname
aws2 s3 cp ./$newname s3://$S3_BUCKET_NAME/
done
这对于文件夹中的文件非常有效out/
,但它完全忽略了,例如out/folder/file
.
理想情况下,我能够对子文件夹执行相同的操作(删除文件名的 .html 部分)并将其传递给我的上传命令。
答案1
shopt -s globstar nullglob
for pathname in out/**/*.html; do
newname=${pathname%.html}
mv "$pathname" "$newname"
aws2 s3 cp "$newname" "s3://$S3_BUCKET_NAME/"
done
这要照顾到
- 不解析输出
ls
(参见“为什么*不*解析`ls`(以及该怎么做)?“)(你的循环还会循环所有其他信息输出ls -l
(权限、所有权、时间戳等),所以我觉得你说它完全有效很奇怪),并且 - 正确引用变量(参见“为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?“), 和
- 将路径名作为实体而不是字符串处理(
sed
等主要用于编辑文本行;当涉及 Unix 上的路径名时,这些可能包含换行符(不太可能,但这是允许的);使用简单的参数替换来删除文件名后缀是比调用sed
(和echo
) 来执行此操作更安全、更快捷),并且 - 在其任何子目录中查找文件名以glob
out
结尾的文件(通过shell 选项启用),以及.html
**
globstar
- 如果模式不匹配任何内容则不运行循环(使用
nullglob
shell 选项)。
另外,它也不需要使用,cd
因为$pathname
和$newname
值将包括从当前目录到任何匹配文件名的完整路径。