在Bash脚本中根据部分文件名与目录查找文件路径的方法
在Bash脚本中基于部分文件名获取完整路径的解决方案
我之前也踩过这个通配符展开的坑!终端里直接跑readlink -f /tmp/*CAR*能正常工作,但放到脚本变量赋值里就失效,核心问题其实有两个:一是当没有匹配到文件时,Bash不会展开通配符,而是把/tmp/*CAR*当作一个字面量字符串传给readlink;二是如果有多个匹配文件,直接赋值给普通变量会因为空格或特殊字符导致路径拆分出错。
下面给你几个靠谱的解决办法:
方法一:用数组处理匹配结果(推荐,支持多文件场景)
Bash数组会自动展开通配符,还能安全处理带空格的文件名,步骤如下:
# 1. 将所有匹配*CAR*的文件路径存入数组 car_matches=(/tmp/*CAR*) # 2. 检查是否有匹配项,避免后续命令出错 if [[ ${#car_matches[@]} -eq 0 ]]; then echo "错误:/tmp目录下未找到包含CAR的文件" >&2 exit 1 fi # 3. 获取单个文件的完整路径(取第一个匹配项) CAR_PATH=$(readlink -f "${car_matches[0]}") echo "找到的文件路径:$CAR_PATH" # 如果需要处理所有匹配文件,用循环遍历数组 for file in "${car_matches[@]}"; do full_path=$(readlink -f "$file") echo "完整路径:$full_path" done
方法二:用find命令实现精准查找
如果需要更灵活的匹配规则(比如递归查找、限定文件类型),find命令是更好的选择:
# 仅查找/tmp目录下(不递归)的文件,文件名包含CAR,输出完整路径 # 用head -n1只取第一个匹配项,去掉则输出所有结果 CAR_PATH=$(find /tmp -maxdepth 1 -type f -name "*CAR*" -exec readlink -f {} \; | head -n 1) # 检查是否找到结果 if [[ -z "$CAR_PATH" ]]; then echo "错误:未找到匹配的文件" >&2 exit 1 fi echo "找到的文件路径:$CAR_PATH"
参数说明:
-maxdepth 1:限制只在/tmp目录下查找,不递归子目录-type f:只匹配普通文件,若要包含目录可改为-type f,d或去掉该参数-exec readlink -f {} \;:对每个匹配的文件执行readlink获取完整路径
为什么原来的写法失效?
终端中直接执行时,Bash会先展开通配符*CAR*为实际文件名,再传给readlink;但在脚本中如果没有匹配到文件,Bash会保留通配符的字面形式,导致readlink尝试解析不存在的路径/tmp/*CAR*,自然得不到正确结果。而数组或find命令能提前处理匹配逻辑,避免这个问题。
内容的提问来源于stack exchange,提问作者Pxlo
相关产品推荐
相关产品推荐

