求助:用awk获取MB/GB级文件完整路径与大小的脚本问题
解决获取MB/GB级文件路径与大小的问题
首先咱们聊聊你当前脚本遇到的几个核心问题:
- 解析
ls输出不可靠:ls -lh的输出里,文件名如果包含空格或特殊字符,awk的$9只能取到文件名的一部分,导致路径错误;而且不同系统的ls输出格式可能有差异,依赖它提取字段很容易出问题。 egrep匹配不全:你用egrep "M|G"只识别到M,大概率是因为部分系统里ls会输出小写的g,或者你的测试文件里刚好没有GB级的文件,保险起见应该匹配大小写的M/G。- 循环处理拆分文件名:
for i in $LIST会把空格当成字段分隔符,导致带空格的文件名被拆成多个条目,循环逻辑直接出错。
下面给你两个解决方案,优先推荐更可靠的find方案:
方案1:用find+awk(最稳定可靠)
这个方法完全避开ls的坑,直接通过文件字节数计算大小,能正确处理所有文件名,还能精确控制筛选条件:
# 查找当前目录下所有文件,输出完整路径和字节数,再转换成MB/GB格式 find "$PWD" -maxdepth 1 -type f -printf "%p:%s\n" | awk '{ # 提取路径和字节数 split($0, parts, ":"); path = parts[1]; bytes = parts[2]; # 判断大小单位并转换 if (bytes >= 1024*1024*1024) { printf "%s:%.2fG\n", path, bytes/(1024*1024*1024) } else if (bytes >= 1024*1024) { printf "%s:%.2fM\n", path, bytes/(1024*1024) } else { next; # 跳过小于1MB的文件 } }' > bigfiles
-maxdepth 1:只查找当前目录(不递归子目录),如果需要递归可以去掉这个参数。-type f:只处理文件,排除目录。- 用字节数计算单位,完全不依赖
ls的输出格式,跨系统通用。
方案2:修复你原有的脚本
如果你一定要基于原脚本修改,这里给你调整后的版本,解决文件名空格和匹配不全的问题:
# 用while read处理带空格的文件名,匹配大小写的M/G while read -r size full_path; do if [[ "$size" =~ [MmGg] ]]; then echo "$full_path:$size" >> bigfiles fi done < <(ls -lh -1 "$PWD"/* | awk '{ # 提取大小字段,以及从第9个字段开始的完整路径 print $5, substr($0, index($0, $9)) }')
substr($0, index($0, $9)):从ls输出中提取完整的文件名(包括空格),因为$9是文件名的起始位置。while read -r:正确读取每行内容,不会把空格当成分隔符。[MmGg]:匹配大小写的M和G,避免漏判小写单位。
运行任意一个方案后,bigfiles里就会每行显示一个文件的完整路径和对应大小,符合你的期望输出。
内容的提问来源于stack exchange,提问作者C0deDaedalus




