OSS文件结尾空白字符导致文件无法删除
OSS文件结尾空白字符导致文件无法删除
2025年7月15日,大模型帮助解决问题,辅助生成总结报告。
遇到一个很奇怪的问题,oss中因为误操作上传的文件名结尾带有'\r'字符,结果这些文件即使执行了删除也能被看到,但是文件下载失败,无法访问。我用ossfs(Python库)能看到这些文件,OSS Browser图形界面也能看到,但是无法获取这些文件,提示key不存在,删除也没效果。
解决问题之前需要开通删除权限,目录下的文件删除权限(OSS都是对象,通过 / 区分目录和文件)。
全过程一句话总结
“把带 \r 的对象 Key 原样写进一个文件,再按行喂给 ossutil rm 即可。”
注意:最好分开操作,不要没有测试就直接删除文件!
1️⃣ 为什么出问题
- OSS 的 Object Key 完全按字节匹配,尾部多一个
\r 就是两个不同文件。 -
ossfs / 控制台虽然能“看见”,但用肉眼看到的名字去删会少一个字节,于是报NoSuchKey。
2️⃣ 解决思路
- 列出对象时用 URL 编码,保证不可见字符变成可见的
%0D。 - URL 解码后把真实 Key(含
\r)写进bad.list。 - 逐行原样传给
ossutil rm,不多加、不少减。
3️⃣ 最简命令链
# 1. 生成 bad.list(一条命令完成)
ossutil ls oss://xxxxx/xxxxxx/xxxx/xxxxxxx/ \
--all-versions --encoding-type url -s \
| awk '{print $NF}' \
| while read -r u; do printf '%b\n' "${u//%/\\x}"; done \
| grep -F $'\r' > bad.list
# 2. 批量删除
cat bad.list | while read -r key; do ossutil rm "$key"; done
4️⃣ 关键知识点速记
| 场景 | 正确姿势 |
|---|---|
看到 ^M 或 %0D |
说明有 \r |
| 删除失败 | 大概率 Key 没对齐,检查字节 |
| 生成删除列表 | URL 解码 → 原样落盘 → 逐行删除 |
| 最快验证 | hexdump -C bad.list 看末尾是否是 0d |
就这样,两步完成:
列 → 写 → 删。
🧰 完整流程(含检查)
# 0️⃣ 环境变量(按自己 bucket/前缀改)
BUCKET=download2
PREFIX=essential-web-v1.0/data-bak/crawl=CC-MAIN-2014-23/
# 1️⃣ 生成候选列表(URL 编码 → 原样 Key)
ossutil ls "oss://${BUCKET}/${PREFIX}" \
--all-versions \
--encoding-type url \
-s \
| awk '{print $NF}' \
| while read -r urlkey; do
rawkey=$(printf '%b' "${urlkey//%/\\x}") # URL 解码
[[ "${rawkey: -1}" == $'\r' ]] && printf '%s\n' "$rawkey"
done > bad.list
# 2️⃣ 肉眼验证:确认每行末尾是 "^M$"
cat -A bad.list # 看到 ...parquet^M$ 就对了
# 也可字节级验证
hexdump -C bad.list | head
# 3️⃣ 批量删除
cat bad.list | while IFS= read -r key; do
ossutil rm "$key"
done
# 4️⃣ 再次确认
ossutil ls "oss://${BUCKET}/${PREFIX}" --encoding-type url -s | grep '%0D$' || echo "已全部删除"
🔍 检查要点速查表
| 工具 | 看到的符号 | 含义 |
|---|---|---|
cat -A bad.list |
^M$ |
行尾确实是 \r\n |
hexdump -C bad.list |
0d 0a |
字节层面确认 \r\n |
grep '%0D$'(URL 编码) |
%0D |
OSS 列表里还有未删对象 |
✅ 一句话记忆
“用 URL 解码拿到真 Key →
cat -A 看见 ^M$ → 逐行原样删除”,三步搞定。
浙公网安备 33010602011771号