Bash脚本中含连字符的文件名处理问题咨询
解决Bash脚本中含连字符文件名的处理问题
问题根源
报错[: syntax error: -' unexpected的直接原因是**变量引用未加双引号导致的单词拆分**。脚本中if [ -f $FILENAME ]这一行,当文件名(比如1f-notworking.log)包含连字符时,Bash会将其拆分为1f和-notworking.log两个部分,[`命令会把`-notworking.log`当成以`-`开头的选项,从而触发语法错误。此外,未加引号的变量在遇到空格时也会出现同样的问题。
修复方案
1. 给所有变量引用添加双引号
这是最关键的修复,确保变量展开时不会被拆分。修改以下几处:
- 将
if [ -f $FILENAME ]改为if [ -f "$FILENAME" ] - 将
files+=($FILE)改为files+=("$FILE") - 将
files+=($FILENAME)改为files+=("$FILENAME")
2. (可选)用Bash内置的[[替代[增强健壮性
[[是Bash专属的条件表达式,不需要担心特殊字符解析问题,语法更灵活。可以把所有[ ... ]替换为[[ ... ]],比如:
if [[ -f "$FILE" ]] && [[ $file_ext == log ]]if [[ -f "$FILENAME" ]] && [[ $dir_ext == log ]]
3. (可选)简化扩展名判断逻辑
直接用通配符匹配替代提取扩展名,代码更简洁:
把file_ext="${FILE##*.}"和[[ $file_ext == log ]]合并为[[ "$FILE" == *.log ]]
修改后的完整脚本
read_files() { files=() if [[ -f "$FILE" ]] && [[ "$FILE" == *.log ]]; then msg "${RED}Parsing file: ${CYAN}$FILE" files+=("$FILE") elif [[ -d "$FILE" ]]; then msg "${RED}Parsing file: ${BLUE}$FILE" # 开启nullglob,避免目录为空时"$FILE"/*变成字面量 shopt -s nullglob for FILENAME in "$FILE"/*; do if [[ -f "$FILENAME" ]] && [[ "$FILENAME" == *.log ]]; then files+=("$FILENAME") fi done # 恢复nullglob默认设置 shopt -u nullglob else msg "${RED}Unable to process: ${CYAN}$FILE .Skipping" fi }
额外说明
shopt -s nullglob的作用是:当目录下没有匹配的文件时,"$FILE"/*会被展开为空字符串,而不是保留"$FILE"/*这个字面量,避免遍历到不存在的文件。- 始终给变量引用加双引号是Bash脚本编写的最佳实践,能避免绝大多数特殊字符(空格、连字符、星号等)带来的问题。
内容的提问来源于stack exchange,提问作者stranger
相关产品推荐
相关产品推荐

