如何从文件完整路径中提取目录名?修改Bash脚本输出目录名而非完整路径的方法
修改Bash脚本以输出目录名而非完整文件路径
我来帮你解决这个问题!你遇到的错误是因为直接把变量filepath替换成dirname是不对的——dirname是一个命令,不是变量,直接替换会让脚本误以为你要操作名为dirname的文件,自然就找不到路径了。
先明确你的需求:要把脚本里输出的完整文件路径改成目录名,我们需要先从传入的完整路径中提取目录部分,再替换到输出逻辑里。
原脚本回顾
#!/bin/bash set -eu filepath=$1 qfilepath=${filepath//\/\\} # Quote backslashes. qfilepath=${qfilepath//"/\"} # Quote doublequotes. file=${qfilepath##*/} # Remove the path. stats=($(stat -c "%s %W %Y" "$filepath")) size=${stats[0]} ctime=$(date --date @"${stats[1]}" +'%d/%m/%Y %H:%M:%S') mtime=$(date --date @"${stats[2]}" +'%d/%m/%Y %H:%M:%S') md5=$(md5sum < "$filepath") md5=${md5%% *} # Remove the dash. printf '"%s","%s",%s,%s,%s,%s\n' \ "$file" "$qfilepath" "$size" "$ctime" "$mtime" $md5
修改后的脚本
#!/bin/bash set -eu filepath=$1 # 从完整路径中提取目录名,用dirname命令处理所有场景更可靠 dirpath=$(dirname "$filepath") # 转义目录名中的特殊字符,保证CSV格式正确 qdirpath=${dirpath//\/\\} # 转义反斜杠 qdirpath=${qdirpath//"/\"} # 转义双引号 file=${filepath##*/} # 提取文件名 stats=($(stat -c "%s %W %Y" "$filepath")) size=${stats[0]} ctime=$(date --date @"${stats[1]}" +'%d/%m/%Y %H:%M:%S') mtime=$(date --date @"${stats[2]}" +'%d/%m/%Y %H:%M:%S') md5=$(md5sum < "$filepath") md5=${md5%% *} # 移除md5sum输出中的横杠 # 把原来输出完整路径的位置换成处理后的目录名 printf '"%s","%s",%s,%s,%s,%s\n' \ "$file" "$qdirpath" "$size" "$ctime" "$mtime" "$md5"
关键修改点说明
- 提取目录名:新增
dirpath=$(dirname "$filepath"),这个命令能完美处理所有路径情况:- 对于
/home/user/doc.txt,返回/home/user - 对于当前目录下的
note.txt,返回.(表示当前目录) - 对于根目录下的
/config.ini,返回/
- 对于
- 转义目录名:复制原来处理
qfilepath的逻辑来处理qdirpath,确保目录名里的反斜杠、双引号等特殊字符不会破坏CSV格式 - 替换输出内容:把
printf里的$qfilepath换成$qdirpath,这样输出的就是目录名而非完整路径了
为什么你之前的尝试会出错?
你直接把filepath替换成dirname,相当于脚本里的$1变成了字符串dirname,脚本会尝试去读取名为dirname的文件,当然会提示“No such file or directory”啦~ 要获取目录名,必须通过命令执行($(dirname "$filepath"))或者参数展开的方式提取,不能直接替换变量名。
内容的提问来源于stack exchange,提问作者simonc
相关产品推荐
相关产品推荐

