如何使用 Bash 进行数据清洗

你可能经历过这样的场景:拿到一个 CSV,以为只是删几行、改几列,结果打开一看:空值、重复、负金额、Windows 换行符,全挤在一起。

别急着打开 Python,很多时候终端里的 Bash 已经能先帮你把这团乱麻冲开。

数据清洗不一定非要一开始就上重型武器(Python),

headcutgrepawksedsortuniq 这些小工具接成一条管道,脏数据就会像河水经过层层筛网,慢慢变清。

Bash vs Python:菜刀和瑞士军刀

Bash 做数据清洗,像在厨房里用一把快刀切菜:快、直接、不用开机预热

Python 更像一台多功能料理机:功能强、适合复杂菜谱,但准备和清洗机器要花点时间

维度 Bash Python
上手成本 Linux/macOS 自带,几乎零安装 需要解释器、虚拟环境、依赖
适合任务 日志、CSV/TSV、文本流、简单 ETL 复杂转换、嵌套 JSON、统计建模
大文件 管道流式处理,内存友好 pandas 默认吃内存,需分块
可读性 短命令优雅,长脚本像咒语 长逻辑更清晰

一句话选择:

  • 数据像一条河:用 Bash,闸门、筛网、管道一接,水就清了。
  • 数据像一团毛线:用 Python,慢慢织,别拿菜刀砍。

先造一份"脏数据"

为了演示,我们构造一份包含典型问题的销售数据 dirty_sales.csv

它的问题包括:

  1. Windows 换行符(看不见,但会导致脚本出错)。
  2. 空值(Bob 的金额缺失)。
  3. 负数金额(David 的金额为 -20)。
  4. 重复数据(Alice 出现了两次)。
  5. 大小写不统一(Beijing 和 BEIJING)。
plain 复制代码
id,name,email,city,amount,date
1,Alice,alice@example.com,Beijing,100,2024-01-01
2,Bob,bob@example.com,Shanghai,,2024-01-02
3,Charlie,charlie@example.com,BEIJING,150,2024-01-03
1,Alice,alice@example.com,Beijing,100,2024-01-01
5,David,david@example.com,Shenzhen,-20,2024-01-05
6,Eve,eve@example.com,Shanghai,200,2024-01-06

一招一招拆掉脏数据

先体检,别急着开刀

对应招式:数据预览与质量检查

脏数据最怕你上来就 sed -i。先看几眼,像医生先看化验单。

bash 复制代码
# 查看前3行,注意观察是否有 ^M (Windows换行符)
head -n 3 dirty_sales.csv

运行结果:

latex 复制代码
id,name,email,city,amount,date
1,Alice,alice@example.com,Beijing,100,2024-01-01
2,Bob,bob@example.com,Shanghai,,2024-01-02

(注:如果文件有 Windows 换行符,行尾可能会显示 ^M)

bash 复制代码
# 查看文件类型和编码
file dirty_sales.csv

运行结果:

latex 复制代码
dirty_sales.csv: CSV text

洗掉看不见的脏:处理换行符

对应招式:文本规范化

Windows 文件常带 \r,它看不见,但能把脚本搞疯(比如让最后一列的值变成 100\r 导致无法计算)。

bash 复制代码
# 删除 \r 并保存为新文件
tr -d '\r' < dirty_sales.csv > step1_crlf.csv
echo "换行符处理完毕"

统一格式:大小写与替换

对应招式:查找替换

城市名 BeijingBEIJING 在统计时会被视为两个城市,需要统一。

bash 复制代码
# 将所有 BEIJING 替换为 Beijing
sed 's/BEIJING/Beijing/g' step1_crlf.csv > step2_case.csv

# 验证:查看包含 Beijing 的行
grep "Beijing" step2_case.csv

运行结果:

latex 复制代码
1,Alice,alice@example.com,Beijing,100,2024-01-01
3,Charlie,charlie@example.com,Beijing,150,2024-01-03
1,Alice,alice@example.com,Beijing,100,2024-01-01

(注:可以看到 Charlie 的城市已经被修正为 Beijing)

安检门:过滤异常值

对应招式:按条件过滤行

awk 是智能闸机。我们要踢掉金额为空(Bob)和金额为负数(David)的行。

bash 复制代码
# 逻辑:保留表头(NR==1) 或者 (第5列不为空 且 第5列大于0)
awk -F',' 'NR==1 || ($5!="" && $5>0)' step2_case.csv > step3_filter.csv

# 查看过滤后的结果
cat step3_filter.csv

运行结果:

latex 复制代码
id,name,email,city,amount,date
1,Alice,alice@example.com,Beijing,100,2024-01-01
3,Charlie,charlie@example.com,Beijing,150,2024-01-03
1,Alice,alice@example.com,Beijing,100,2024-01-01
6,Eve,eve@example.com,Shanghai,200,2024-01-06

(注:Bob 的空值和 David 的 -20 已经被移除)

排队点名:去重

对应招式:排序与去重

Alice 的记录重复了(id 都是 1)。我们可以用 sort 去重。

bash 复制代码
# 先提取表头,再对剩余内容去重,最后合并
head -n 1 step3_filter.csv > step4_unique.csv
tail -n +2 step3_filter.csv | sort -t',' -k1,1n -u >> step4_unique.csv

# 查看最终结果
cat step4_unique.csv

运行结果:

latex 复制代码
id,name,email,city,amount,date
1,Alice,alice@example.com,Beijing,100,2024-01-01
3,Charlie,charlie@example.com,Beijing,150,2024-01-03
6,Eve,eve@example.com,Shanghai,200,2024-01-06

(注:重复的 Alice 记录已消失,只剩下唯一的一条)

聚合统计:awk 做小报表

对应招式:聚合统计

数据干净了,现在可以快速算一下各城市的销售总额。

bash 复制代码
# 按城市(第4列)分组,求金额(第5列)之和
awk -F',' 'NR>1 {city[$4]+=$5} END{for(c in city) print c, city[c]}' step4_unique.csv

运行结果:

latex 复制代码
Beijing 250
Shanghai 200

(注:Beijing = 100+150, Shanghai = 200)

终极招式:一键清洗脚本

把上面的招式串成一条管道,瞬间完成清洗:

bash 复制代码
#!/usr/bin/env bash
set -euo pipefail

INPUT="dirty_sales.csv"
OUTPUT="final_clean.csv"

# 1. 去除 \r -> 2. 统一大小写 -> 3. 过滤空值和负数 -> 4. 去重
cat "$INPUT" \
  | tr -d '\r' \
  | sed 's/BEIJING/Beijing/g' \
  | awk -F',' 'NR==1 || ($5!="" && $5>0)' \
  | awk -F',' '!seen[$0]++' \
  > "$OUTPUT"

echo "清洗完成!结果如下:"
cat "$OUTPUT"

最终运行结果:

latex 复制代码
清洗完成!结果如下:
id,name,email,city,amount,date
1,Alice,alice@example.com,Beijing,100,2024-01-01
2,Bob,bob@example.com,Shanghai,,2024-01-02
3,Charlie,charlie@example.com,Beijing,150,2024-01-03
5,David,david@example.com,Shenzhen,-20,2024-01-05
6,Eve,eve@example.com,Shanghai,200,2024-01-06

(注:这里演示的是最简管道,实际生产中建议按前文分步逻辑处理复杂情况)

总结

Bash 数据清洗的精髓不是"所有事都自己做",而是:用管道把小事串起来,把脏数据变成干净的数据流。

  • 用 Bash: 处理日志、大文件流式清洗、简单的列裁剪和去重。
  • 用 Python: 处理复杂嵌套 JSON、需要跨行逻辑计算、或者要做统计建模时。

当你把 headgrepawksed 当成一排小工具,清洗数据就会像整理一条河:不慌,不急,水自然会清。

相关推荐
wang_yb1 小时前
如何使用 Bash 进行数据清洗
数据分析·databook
kaiyou20261 小时前
秋招投市场分析岗,没有实习可以做什么项目?
数据分析
蓝速科技3 小时前
便民服务大厅 AI 数字人一体机场景适配与落地指南丨蓝速科技
大数据·网络·数据结构·人工智能·自然语言处理·数据分析·运维开发
Patrick在香港5 小时前
Python 审计香港开放数据目录:两个端点差 10 倍,只有 9.3% 的资源标了「最后修改时间」
开发语言·数据库·python·数据分析·api·数据治理·开放数据
IT毕设梦工厂5 小时前
计算机毕业设计选题推荐:基于大数据的草鱼价格分析与可视化|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目
大数据·hadoop·python·数据挖掘·数据分析·课程设计·大数据毕设项目
data analyse 4566 小时前
LTV和CAC怎么算?把网站数据接到生意账上
数据分析
SL_staff7 小时前
插单风险的数据闭环治理:JVS-BI 在制造业实时预警中的技术实践
java·数据分析·数据可视化
数据智研8 小时前
【数据分享】300个城市-5G试点城市DID数据(2014-2025)
大数据·运维·人工智能·信息可视化·数据分析
Mr数据杨9 小时前
基于企业交易数据的OKVED行业分类实战解析
人工智能·数据分析·kaggle竞赛