ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

The Missing Semester 中文版 · 数据整理(Data Wrangling):用命令行管道把日志变成答案

The Missing Semester 中文版 · 数据整理(Data Wrangling):用命令行管道把日志变成答案 文档教程教育【免费下载链接】missing-semester-cn.github.iothe CS missing semester Chinese version项目地址https://gitcode.com/gh_mirrors/mi/missing-semester-cn.github.io点击查看免费下载数据整理Data Wrangling是 The Missing Semester计算机教育中缺失的一课中文站 2020 课程系列 的核心实战章节它的本质是不断把一种格式的数据转换成另一种格式直到得到你真正想要的最终结果。本文以 数据整理讲义 为骨架结合本仓库的课程源码与配套资源完整讲解grep、sed、sort、uniq、awk、paste、bc、R、gnuplot、xargs在管道中的组合用法。读完本文你将能从一个遥不可及的远程系统日志出发经过层层过滤、清洗、聚合与统计最终得到一份可直接使用的分析结论——并具备把任意文本/二进制数据流改造成所需格式的实战能力。引言管道即数据整理在 课程概览与 shell 中我们学过|操作符允许将一个程序的输出连接到另一个程序的输入、、则用于重定向文件流。其实每当你使用管道运算符的时候你已经在进行某种形式的数据整理。例如一条最简单的命令journalctl | grep -i intel它把所有系统日志journalctl 输出转换成仅包含 intel不区分大小写的日志。这虽然朴素但已经完整展示了数据整理的三个要素明确输入数据源、选对工具、按序组合工具。数据整理最典型的使用场景是日志分析日志往往非常庞大逐条通读不现实我们需要的是先筛选、再提取、后聚合。从远程日志到目标数据第一层管道假设我们要查明哪些用户曾尝试登录我们的服务器。第一步通过 SSH 获取远端日志ssh myserver journalctl内容太多了。先过滤出涉及 sshd 的行ssh myserver journalctl | grep sshd注意这里我们用管道把远端服务器上的文件流传输到本机grep程序——ssh支持在标准输出上透传远端命令输出这正是远程数据整理的魔力所在。进一步收窄范围ssh myserver journalctl | grep sshd | grep Disconnected from | less外层单引号的作用让journalctl | grep sshd | grep Disconnected from这段管道在远端机器上先执行完毕再把过滤后的结果通过网络传回本机避免把整个巨型日志流下载到本地再过滤极大节省流量。less是文件分页器可翻页浏览长文本。为了彻底避免重复网络传输还可以把结果落盘$ ssh myserver journalctl | grep sshd | grep Disconnected from ssh.log $ less ssh.log由本地 shell 负责重定向把远端过滤结果写入ssh.log。sed流编辑器与替换命令过滤结果中仍有大量噪音。处理这种问题最强大的工具之一是sed——一个基于古老文本编辑器ed构建的流编辑器stream editor。它的工作方式不是直接修改文件内容而是向它提供一条条简短命令来描述如何修改流经它的每一行当然也可以选择直接改文件。最常用的命令是s即替换substitutionssh myserver journalctl | grep sshd | grep Disconnected from | sed s/.*Disconnected from //s命令的通用语法是s/REGEX/SUBSTITUTION/REGEX要搜索的正则表达式SUBSTITUTION用于替换匹配文本的字符串有趣的是这个语法与 Vim 讲座中的搜索和替换高度相似——在 Vim 进阶 · 搜索和替换 一节中%s/foo/bar/g正是同一套替换思想的编辑器版本。学习一个工具往往有助于熟练使用另一个工具sed与 Vim、Perl 的正则语法可以互相印证。正则表达式基础正则表达式regex极其常见且有用值得花时间真正理解。让我们拆解上面用到的/.*Disconnected from /。正则通常但不总是以/包围。大多数 ASCII 字符表示其字面含义少数字符具有特殊的匹配行为且具体语义因正则实现而异——这是初学者最常感到沮丧的地方。常见模式模式含义.除换行符之外的任意单个字符*匹配前面字符零次或多次匹配前面字符一次或多次[abc]匹配a、b、c中的任意一个(RX1\|RX2)匹配RX1或RX2二者之一^行首$行尾sed的正则有些奇怪大部分上述元字符需要加\才具备特殊含义或者直接使用-E选项启用扩展正则ERE。回到/.*Disconnected from /它匹配任意数量字符开头 字面字符串Disconnected from的任何文本。但正则很容易写错——假设有人真的用Disconnected from作为用户名登录Jan 17 03:13:00 thesquareplanet.com sshd[2631]: Disconnected from invalid user Disconnected from 46.97.239.16 port 55920 [preauth]由于*和默认是贪婪模式尽可能多地匹配上述字符串的匹配结果会变成46.97.239.16 port 55920 [preauth]这显然不是我们想要的。某些正则实现允许在*或后追加?使其变成非贪婪模式但sed不支持可以切换到 Perl 命令行模式perl -pe s/.*?Disconnected from //本节后续仍以sed为主因为它是这类任务的通用工具。sed还能打印匹配后的行、一次调用执行多次替换等但其功能面太广往往有更聚焦的替代工具。匹配整行并保留用户名捕获组还需要去掉用户名后面的后缀。麻烦在于用户名本身可以包含空格因此需要匹配一整行| sed -E s/.*Disconnected from (invalid |authenticating )?user .* [^ ] port [0-9]( \[preauth\])?$//逐段拆解可借助在线正则调试器逐步验证.*Disconnected from与前文一致的开头匹配(invalid |authenticating )?两种user前缀?表示该组可有可无user .*匹配user及其后属于用户名的任意字符[^ ]任意非空且不包含空格的序列一个单词port [0-9]字面port加一串数字( \[preauth\])?$可能存在的[preauth]后缀然后是行尾。由于整行被替换日志内容会全部变成空字符串。要保留用户名需要捕获组capture groups被圆括号括住的正则所匹配的文本会按编号存入捕获组替换字符串中可用\1、\2、\3引用| sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/\2即第二个捕获组——用户名部分前两个捕获组是(invalid |authenticating )?与(.*)。此时即使某用户名恰好是Disconnected from也不会再干扰结果因为整个行模式已被完整锚定。正则复杂到可以匹配电子邮箱地址有大量专门讨论与测试用例、测试矩阵甚至有人写出了判断一个数是否为质数的正则。正则以其难写对著称但仍是工具箱中的常备利器。回到数据整理排序、去重、取 Top N现在我们有了一条完整的用户名提取管道ssh myserver journalctl | grep sshd | grep Disconnected from | sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/sed本身还能完成更多花样例如i命令文本注入p命令显式打印特定行按索引选择特定行。详见man sed。而只用 sed 也能完成过滤这件事本仓库英文原版讲义给出了一个等价示例用sed -E -e /Disconnected from/!d -e s/.../\2/两条表达式分别完成删除不匹配行与提取用户名供爱好者对比参考。接下来统计最常出现的登录用户。sort对输入排序uniq -c把连续相同的行折叠成一行并在行首加上出现次数ssh myserver journalctl | grep sshd | grep Disconnected from | sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/ | sort | uniq -c | sort -nk1,1 | tail -n10sort -n按数字顺序排序默认按字典序-k1,1仅基于以空格分隔的第一列排序,n表示排序到第 n 个部分为止默认到行尾——本例按整行排序也行这里主要是演示该参数tail -n10取前 10 名。想要登录次数最少的用户用head代替tail或使用sort -r倒序排列。提取用户名并合并成一行paste 与 awk 的初遇结果仍是一行一个用户名。希望只输出用户名、并用逗号合并成一行ssh myserver journalctl | grep sshd | grep Disconnected from | sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/ | sort | uniq -c | sort -nk1,1 | tail -n10 | awk {print $2} | paste -sd,paste -s把多行合并为一行paste -d,指定单字符分隔符为逗号awk {print $2}输出每行的第二个字段即用户名。macOS 注意该命令无法直接配合系统默认的 BSDpaste使用相关讨论见 课程概览与 shell 的习题内容。awk一种碰巧擅长处理文本的编程语言awk本质上是一门编程语言只是它特别擅长处理文本流。它接受一个可选的模式pattern加一个代码块block当某行匹配模式时执行代码块。默认模式匹配所有行。{print $2}的含义代码块内$0表示整行内容$1~$n表示按域分隔符切分后的第 n 个域默认以空白分隔可用-F修改。上述命令即对每一行打印第二个域——用户名。再进一步统计以c开头、e结尾、且仅尝试过一次登录的用户名数量| awk $1 1 $2 ~ /^c[^ ]*e$/ { print $2 } | wc -l模式部分{...}之前要求第一域等于1即uniq -c得到的计数值且第二域匹配正则/^c[^ ]*e$/代码块打印用户名wc -l统计输出行数。awk既然是编程语言就可以写更完整的程序BEGIN { rows 0 } $1 1 $2 ~ /^c[^ ]*e$/ { rows $1 } END { print rows }BEGIN模式匹配输入的开头END匹配结尾每个匹配行将第一域累加到rows最后输出总和。事实上awk的能力足以完全取代grep和sed可参考 idiomatic awk 一类的资料具体改写留作读者课后练习。分析数据数学计算、统计与绘图管道流还可以做数学计算。将每行数字加起来| paste -sd | bc -lpaste -sd把每行一个的数字用连接成一行表达式交给任意精度计算器bc -l求值。更复杂的表达式echo 2*($(data | paste -sd)) | bc -l利用$(...)命令替换把管道结果内嵌进算术表达式。获取统计信息有多种途径st工具干净利落如果已安装 R数据分析与绘图语言如 ggplot2可以把管道输出喂给它ssh myserver journalctl | grep sshd | grep Disconnected from | sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/ | sort | uniq -c | awk {print $1} | R --slave -e x - scan(filestdin, quietTRUE); summary(x)awk {print $1}提取计数列R --slave -e ...以非交互方式执行 R 表达式scan(filestdin, quietTRUE)从标准输入读取数字向量summary(x)输出该向量的统计摘要。需要简单绘图时gnuplot是得力助手ssh myserver journalctl | grep sshd | grep Disconnected from | sed -E s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ] port [0-9]( \[preauth\])?$/\2/ | sort | uniq -c | sort -nk1,1 | tail -n10 | gnuplot -p -e set boxwidth 0.5; plot - using 1:xtic(2) with boxes-p绘制后保持窗口-e执行 gnuplot 命令plot - using 1:xtic(2) with boxes从标准输入读取数据第一列为数值、第二列作为 X 轴刻度标签绘制柱状图。用数据整理生成命令参数xargs 实战数据整理另一个常见用途是根据一份较长列表找出需要安装或移除的东西。此前讨论的技术配合xargs威力巨大rustup toolchain list | grep nightly | grep -vE nightly-x86 | sed s/-x86.*// | xargs rustup toolchain uninstall流程拆解rustup toolchain list列出所有已安装工具链grep nightly筛选 nightly 相关条目grep -vE nightly-x86-v反向匹配排除含nightly-x86的行-E启用扩展正则sed s/-x86.*//去掉-x86及其后的架构后缀得到工具链名xargs rustup toolchain uninstall把每行结果作为参数传给卸载命令。xargs把管道输出转成命令行参数这是连接数据整理与后续动作的关键桥梁。注意本仓库中文讲义与英文原版在此处的过滤表达式略有差异英文版额外排除01-17日期条目以你本机实际工具链列表为准。整理二进制数据ffmpeg convert gzip ssh数据整理不仅限于文本对二进制数据同样适用。下面这条管道从摄像头抓取一帧图像、转为灰度、压缩、经 SSH 传至远端并解压显示ffmpeg -loglevel panic -i /dev/video0 -frames 1 -f image2 - | convert - -colorspace gray - | gzip | ssh mymachine gzip -d | tee copy.jpg | env DISPLAY:0 feh -ffmpeg -loglevel panic -i /dev/video0 -frames 1 -f image2 -从/dev/video0抓取 1 帧输出到标准输出--loglevel panic只显示致命错误convert - -colorspace gray -ImageMagick 的convert读取标准输入转为灰度图后写回标准输出gzip压缩数据流ssh mymachine gzip -d | tee copy.jpg | env DISPLAY:0 feh -远端解压tee同时落盘copy.jpg再由feh图形查看器显示在远端屏幕DISPLAY:0。整条链的输入输出都是字节流-约定表示标准输入/输出这正是数据整理思想在二进制世界的延伸。课后练习把知识变成肌肉记忆本讲附带的练习与 习题解答 入口对应建议逐题实操学习交互式正则表达式教程覆盖大部分基础语法。统计/usr/share/dict/words中包含至少三个a且不以s结尾的单词个数再找出这些单词中出现频率前三的末尾两个字母。可用sed的y命令或tr程序处理大小写并回答共有多少种词尾两字母组合哪个组合从未出现过原地替换陷阱sed s/REGEX/SUBSTITUTION/ input.txt input.txt看上去很诱人但这是不明智的做法——思考为什么提示重定向会在sed读取完成前就截断/清空输入文件查看man sed确认并思考这是否是sed特有。统计最近十次开机的开机时间平均数、中位数与最长时间。Linux 用journalctlmacOS 用log show分别找到每次开机开始Logs begin at ...与结束systemd[577]: Startup finished in ...的时间戳。对比最近三次重启启动信息中不同的部分使用journalctl的-b选项获取历史启动日志可用sed 0,/STRING/d删除某个匹配串之前的内容随后过滤掉时间戳等每次必变的部分用uniq计数再删除出现 3 次的行即三次启动共有的内容。从在线公开数据集提取两列数值用curl获取数据HTML 数据可用pup解析JSON 数据可用jq然后用一条指令求某一列的最大值与最小值再用另一条指令计算两列之差的绝对值总和。结语数据整理的思维模型回顾整条探索路径数据整理的方法论其实非常固定明确数据源与目标——从ssh myserver journalctl的原始日志到最常登录的用户名列表层层筛选——grep缩小范围sed清洗格式awk按字段/条件精炼聚合与统计——sortuniq -c计数sort -nk1,1排行paste/bc/R/gnuplot做数学与可视化驱动后续动作——xargs把结果变成命令参数。这条管道贯穿了 2020 课程系列 中 shell 重定向与管道的基础也呼应了仓库中日志相关演示例如 static/files/logger.py 演示了带级别与格式的日志输出可作为本讲管道练习的本地数据源。正如讲义所说大多数数据整理工作本质上是知道有哪些工具、以及如何组合它们。掌握这套组合拳日志分析、配置清理、数据抽取等日常任务都会变得举重若轻。赞分享文档教程教育【免费下载链接】missing-semester-cn.github.iothe CS missing semester Chinese version项目地址https://gitcode.com/gh_mirrors/mi/missing-semester-cn.github.io点击查看免费下载相关推荐从零开始的命令行环境完整指南10个实用技巧掌握终端操作从零开始的命令行环境完整指南10个实用技巧掌握终端操作 命令行环境 是每位开发者必备的核心技能但大学课程常常忽略这一关键领域。本文将带你系统学习命令行环境的文档教程命令行环境实战指南别名、Shell 框架、终端复用器与现代 CLI 工具The Missing Semester 中文版命令行环境实战指南别名、Shell 框架、终端复用器与现代 CLI 工具The Missing Semester 中文版 本篇技术指南来自《计算机教育中缺文档教程教育CANN/asc-devkit算子入图开发指南概述a nameZH CN_TOPIC_0000001985173748 /a 图模式是神经网络模型的一种运行模式在图模式下用户首先将模型的计算过程文档教程教育上一篇如何用Mermaid Live Editor在5分钟内创建专业图表免费在线工具终极指南下一篇彻底解决Vitest循环依赖从报错到根治的实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表