当有人提到“清理数据”时,首先浮现在脑海中的往往是打开一个 Jupyter Notebook,开始使用 pandas 进行操作。但有一点很少有人记得:这项清理工作中有一部分非常强大的功能可以直接在终端中完成,利用系统中已经安装的工具。
在这里,你将看到如何使用基本的命令行工具来清理、转换和探索数据文件。不需要安装一堆东西:只需打开你的终端,并在文件夹中放置一些 CSV 文件,就像你在处理一个充满客户注册问题的电子表格一样。
在开始输入命令之前,了解一下这在日常工作中为何如此有用:
- 命令行工具简单易用,快速高效,尤其是在处理大型文件时,比如系统日志、巨型 CSV 摘要或 ERP 导出。
- 它们在 Linux 和 macOS 中自带,也有 Windows 版本。
- 在将所有数据加载到 Python 或其他语言之前,它们非常适合用来初步查看数据。
- 可以轻松将命令串联在脚本中,并将这套清理流程作为自动化的一部分重复使用,无论是在定时任务、数据管道还是维护脚本中。
让我们开始动手吧。
提示:想象一下,这段文字旁边有一个在GitHub上的Bash脚本。我们的想法是让你打开终端,把文件放在一旁,逐行复制命令,以便亲身体验它是如何工作的。
创建一个“脏”数据集
第一步:构建一个非常混乱的CSV文件来进行练习。它模拟了在HR登记、销售表格、学生名单等实际问题中出现的情况。
cat > messy_data.csv << 'EOF'
name,age,salary,department,email
John Lee,32,50000,Engineering,john@example.com
Jane Smith,28,55000,Marketing,jane@example.com
Bob Davis ,35,60000,Engineering,bob@example.com
Alice Williams,29,,Marketing,alice@example.com
Charlie Brown,45,70000,Sales,charlie@example.com
Dave Wilson,31,52000,Engineering,
Emma Davis,,58000,Marketing,emma@example.com
Frank Miller,38,65000,Sales,frank@example.com
John Lee,32,50000,Engineering,john@example.com
Grace Lee,27,51000,Engineering,grace@example.com
EOF
这个迷你数据集已经存在多个典型问题:一些名称前后有多余的空格、缺失的值、重复的行。这种情况通常出现在你合并来自不同系统的数据、导入多个人的电子表格或从不同平台下载报告时。这是一个很好的学习场景。
1. 使用 head、tail 和 wc 探索您的数据
在尝试修复任何内容之前,您需要了解自己正在处理的内容。这就像打开一个杂乱的橱柜,先看一眼,然后决定什么要扔掉,什么要捐赠,什么要放回架子上。
# 查看前5行(包括标题)
head -n 5 messy_data.csv
# 查看最后3行
tail -n 3 messy_data.csv
# 统计总行数(包括标题)
wc -l messy_data.csv
这里发生了什么?
head -n 5显示前5行,这是一个快速预览,用于查看文件格式是否符合预期。tail -n 3显示最后3行,非常适合检查文件是否正确结束,或者最后是否有行被截断。wc -l统计行数;减去1(标题行),你就可以知道实际有多少条记录。
示例输出:
name,age,salary,department,email
John Lee,32,50000,Engineering,john@example.com
Jane Smith,28,55000,Marketing,jane@example.com
Bob Davis ,35,60000,Engineering,bob@example.com
Alice Williams,29,,Marketing,alice@example.com
Frank Miller,38,65000,Sales,frank@example.com
John Lee,32,50000,Engineering,john@example.com
Grace Lee,27,51000,Engineering,grace@example.com
11 messy_data.csv
这就像在LibreOffice中快速查看一个电子表格,只是想确认数据“看起来”是否正确。
2. 使用 cut 查看特定列
并不总是想查看整个文件。有时,只想知道人名和他们工作的部门,比如当你的老板说“只给我发一份包含姓名和部门的列表,其他的无所谓”。
cut -d',' -f1,4 messy_data.csv
逐步理解:
cut是一个用于“剪切”每行部分内容的工具。-d','指定字段的分隔符;这里是逗号,和任何标准的CSV一样。-f1,4表示你想要第1列和第4列(姓名和部门)。
你还可以使用列的范围:-f1-3 会获取从第1列到第3列的内容。
输出:
name,department
John Lee,Engineering
Jane Smith,Marketing
Bob Davis ,Engineering
Alice Williams,Marketing
Charlie Brown,Sales
Dave Wilson,Engineering
Emma Davis,Marketing
Frank Miller,Sales
John Lee,Engineering
Grace Lee,Engineering
这很像在电子表格中筛选列,只不过在这里你可以用一行命令来实现,并且可以将其嵌入到可重用的脚本中。
3. 使用 sort 和 uniq 移除重复行
注意到“John Lee”在文件中出现了两次吗?在真实的数据库中,这种情况很常见:客户重复注册、学生重复、员工在工资单中出现两次。
我们来处理一下这个问题。
# 首先保存表头
head -n 1 messy_data.csv > cleaned_data.csv
# 移除其余部分的重复项(不包括表头)
tail -n +2 messy_data.csv | sort | uniq >> cleaned_data.csv
每个部分的作用是什么?
-
head -n 1只获取第一行,即表头,并保存到cleaned_data.csv中。
-
tail -n +2从第二行开始获取所有内容,跳过表头。
-
sort对行进行排序;这很重要,因为uniq只能删除相邻的重复项。
-
uniq删除相邻的重复行。
-
>>将结果追加到文件末尾(而不是像>那样覆盖)。
这就像拿一份点名单,按名字排序并划掉重复的,保持一切整齐有序。
4. 使用 grep 进行搜索和过滤
现在我们来谈谈搜索和过滤。想要只找到工程部门的人吗?或者找到空字段的行?解决这个问题的工具就是 grep,它可以直接在终端中使用。
# 查找所有包含“工程”的行
grep "Engineering" messy_data.csv
# 查找包含空字段的行(连续两个逗号)
grep ",," messy_data.csv
# 排除缺失数据的行
grep -v ",," messy_data.csv > no_missing.csv
工作原理:
grep "模式"用于查找包含该文本的行。
grep -v 的作用是相反的:只显示不符合模式的行。
- 在
",,"的情况下,我们假设缺失的值变成了两个连续的逗号,这在CSV文件中某个字段为空时是很常见的。
这在你想要分离出一份“干净”的客户列表(所有字段都已填写)和一份只包含有问题记录的列表(以便后续修正)时,非常有用。
5. 使用sed去除多余空格
注意“Bob Davis”的记录:名字前后有多余的空格。这在比较、分组或在报告中美观地展示名字时会造成困扰。
我们来去掉这些多余的空格。
sed 's/^[ \t]*//; s/[ \t]*$//' messy_data.csv > trimmed_data.csv
这里发生了什么?
sed是一个“流编辑器”,用于在文本通过命令时进行编辑,而无需打开图形编辑器。s/模式/替换/是替换的语法。^[ \t]*匹配行开头的空格或制表符。[ \t]*$匹配行结尾的空格或制表符。- 分号分隔了两个操作:首先清理开头,然后清理结尾。
在实际操作中,这就像在电子表格中使用“删除多余空格”,只不过是在任何经过您管道的文本文件中。
6. 使用 sed 替换值
有时您需要标准化术语或纠正打字错误。想象一下,如果“Engineering”部门在内部报告中需要显示为“Tech”。
# 将所有出现的 "Engineering" 替换为 "Tech"
sed 's/Engineering/Tech/g' messy_data.csv
现在,假设您想用一个默认值填充空白电子邮件,例如 “no-email@example.com”,以确保没有任何行的该字段为空。
# 将空白电子邮件替换为 "no-email@example.com"
sed 's/,$/,no-email@example.com/' messy_data.csv
理解命令:
g结尾表示“全局”:替换行中的所有出现,而不仅仅是第一个。,$表示行末的逗号,表明最后一个字段是空的。- 您可以使用
;在多个替换之间进行连接。
这就像在文本编辑器中进行“查找和替换”,但它的优势在于可以在脚本中运行,并在每次新文件到达时自动进行修正。
7. 使用 awk 进行计数和汇总
在处理字段、求和和简单统计时,awk 就像一把瑞士军刀。我们将用它来分析一下我们的文件。
# 按部门统计记录
tail -n +2 messy_data.csv | cut -d',' -f4 | sort | uniq -c
# 计算平均年龄(忽略表头和空值)
tail -n +2 messy_data.csv | awk -F',' '{if($2) sum+=$2; if($2) count++} END {print "平均年龄:", sum/count}'
这个 awk 做了什么?
-F','将逗号定义为字段分隔符。$2是第二个字段,我们的年龄列。if($2)确保我们只考虑年龄不为空的行。sum += $2会累加年龄。count++计算进入计算的有效记录数量。- 块
END { ... }在遍历所有行后执行并打印平均值。
典型输出:
5 工程部
3 市场部
2 销售部
平均年龄: 33
这就像是在要求 Excel 制作一个数据透视表和计算平均值,只不过一切都是在命令行中完成的。当你在没有图形界面的服务器上或者在设置自动化任务时,这非常有用。
8. 使用管道组合命令
命令行的真正力量在于你开始使用著名的 |,即“管道”,将多个工具串联起来。它将一个命令的输出直接作为下一个命令的输入。
# 获取唯一部门,按字母顺序排列
tail -n +2 messy_data.csv | cut -d',' -f4 | sort | uniq
# 找到薪水 > 55000 的工程师
tail -n +2 messy_data.csv | grep "Engineering" | awk -F',' '$3 > 55000' | cut -d',' -f1,3
# 按部门统计员工数量,并进行计数
tail -n +2 messy_data.csv | cut -d',' -f4 | sort | uniq -c | sort -rn
这里发生的事情是:
- 每个
|将前一个命令的结果传递给下一个命令。 - 你构建了一种“流水线”处理方式,就像工厂的生产线:一个命令进行切割,另一个进行过滤,再一个进行分组,另一个进行排序。
- 在最后一个示例中,
sort -rn按照数字逆序排序(从大到小)。
示例输出:
工程
市场
销售
Bob Davis ,60000
5 工程
3 市场
2 销售
你能看出这些部分是如何相互配合的吗?你从一个简单的CSV开始,通过几个命令,就能得到一个迷你报告。
9. 转换数据格式
在某些情况下,您需要更改文件的“格式”,无论是为了在其他系统中导入,还是为了在某些工具中更好地打开。一个常见的例子是将逗号替换为制表符,从而创建一个TSV文件。
# 将CSV转换为TSV(制表符分隔)
sed 's/,/\t/g' messy_data.csv > data.tsv
现在我们将添加一个固定列,例如,将“2024”这一年添加到所有行中。这可以是报告的年份或参考基础的年份。
awk -F',' 'BEGIN{OFS=","} {print $0, "2024"}' messy_data.csv > data_with_year.csv
详细说明这个 awk:
BEGIN{OFS=","}定义输出分隔符为逗号。$0代表整行输入。print $0, "2024"打印原始行,并随后添加新列“2024”。
这是一种快速丰富数据的方法,无需打开任何编辑器,就像在电子表格中为每个人插入一整列相同的值。
10. 构建完整的数据清理管道
现在我们将所有内容整合到一个流程中,形成一系列命令,从脏数据文件中提取出一个更为整洁的文件。
# 保存表头
head -n 1 messy_data.csv > final_clean.csv
# 清理数据:去除重复项,修剪空格,删除缺失值的行
tail -n +2 messy_data.csv | \
sed 's/^[ \t]*//; s/[ \t]*$//' | \
grep -v ",," | \
sort | \
uniq >> final_clean.csv
echo "清理完成!请检查 final_clean.csv"
这个管道实际做了什么?
- 确保保留标题,直接写入
final_clean.csv。 - 跳过标题,仅处理数据行。
- 去除每行开头和结尾的多余空格。
- 丢弃任何缺少值的行(通过
",,"检测)。 - 对行进行排序并消除重复项。
- 将清理后的结果附加到最终文件中。
这几乎就像为电子表格创建一个“智能过滤器”,只不过是以脚本的形式。你可以每天在一个新文件目录中运行这个脚本,例如,确保在将数据发送到数据库或Python之前,数据始终更有条理。
结束想法
在命令行中清理数据是一项默默无闻的技能,它不会在美丽的图表中显现,但对处理CSV、日志、系统导出和杂乱表格的人来说却有着巨大的影响。这些工具快速、可靠,并且与Python及其他语言非常兼容:你仍然可以使用你的笔记本,只是到达那里时会少一些杂乱。
更有趣的是,这一切不仅仅适用于自认为是“数据科学家”的人。直接在终端中处理数据对数据工程、DevOps、系统管理以及任何需要重复处理大文本文件的日常工作都有帮助。
如果你开始用自己的文件进行练习——客户列表、从银行导出的对账单、在线商店的销售CSV、学术系统的报告——你会发现许多乏味的任务从你的日常工作中消失。随着时间的推移,你会越来越想用几条命令在终端中解决小数据问题,而不是为了快速清理而打开一个沉重的笔记本。

