大数据开发学习Day10
一、Linux / Shell
tee 双向输出 + head/tail 日志查看
1. tee命令:从标准输入读取数据,同时输出到标准输出(屏幕) 和一个或多个文件
tee [选项] [文件...]
-a, --append 追加到文件末尾,而不是覆盖
-i, --ignore-interrupts 忽略中断信号
--help 显示帮助信息
--version 显示版本信息
1.1 基本用法:同时输出到屏幕和文件
//将 echo 的输出同时显示在屏幕并写入 file.txt
echo "Hello World" | tee file.txt
//输出到多个文件
echo "Hello" | tee file1.txt file2.txt file3.txt
1.2 追加模式:不覆盖原有内容
echo "New line" | tee -a existing.log
1.3 隐藏屏幕输出
//只想写入文件,不想看屏幕输出
echo "Secret" | tee secret.txt > /dev/null
1.4 配合 sudo 写入受保护文件
//向需要root权限的文件写入内容
echo "127.0.0.1 example.com" | sudo tee -a /etc/hosts
1.5 在管道中同时保存中间结果
//统计命令执行过程中某个阶段的数据
cat large_file.txt | tee temp.txt | grep "error" | wc -l
//temp.txt 保存了完整内容,便于后续分析
1.6 进程替换:同时给多个命令提供数据
//一份数据同时给两个不同的命令处理
echo -e "apple\nbanana\ncherry" | tee >(sort) >(wc -l) > /dev/null
2. head 命令:输出文件的开头部分,默认显示前 10 行
head [选项] [文件...]
-n N, --lines=N 显示前 N 行
-c N, --bytes=N 显示前 N 个字节
-q, --quiet, --silent 不显示文件名标题(多文件时)
-v, --verbose 总是显示文件名标题
--help 显示帮助信息
2.1 基本用法:显示前10行
//默认显示前10行
head file.txt
//指定显示前20行
head -n 20 file.txt
head -20 file.txt # 简写形式
2.2 显示前 N 个字节
//显示前100个字节
head -c 100 file.txt
//显示前1KB(1024字节)
head -c 1024 file.txt
2.3 处理多个文件
//显示多个文件的前5行,会自动显示文件名标题
head -n 5 file1.txt file2.txt file3.txt
# 输出示例:
# ==> file1.txt <==
# line1
# line2
# ...
# ==> file2.txt <==
# line1
# ...
//禁止显示文件名标题
head -q -n 5 file1.txt file2.txt
2.4 与其他命令组合
//查看进程列表的前10个
ps aux | head -10
//查看日志文件的前50行
head -50 /var/log/syslog
//排除最后100行,只显示前面的内容(结合 tail 使用)
head -n -100 file.txt # 显示除了最后100行之外的所有内容
2.5 负数的特殊用法
//显示除了最后5行之外的所有行
head -n -5 file.txt
//显示除了最后20字节之外的所有内容
head -c -20 file.txt
3. tail 命令:输出文件的结尾部分,默认显示后 10 行
tail [选项] [文件...]
-n N, --lines=N 显示最后 N 行
-c N, --bytes=N 显示最后 N 个字节
-f, --follow 实时跟踪文件新增内容
-q, --quiet, --silent 不显示文件名标题
-v, --verbose 总是显示文件名标题
3.1 基本用法:显示最后10行
//默认显示最后10行
tail file.txt
//显示最后20行
tail -n 20 file.txt
tail -20 file.txt # 简写形式
3.2 实时监控日志(最常用)
//实时跟踪日志文件的新增内容
tail -f /var/log/syslog
//实时跟踪,并显示最后50行
tail -n 50 -f app.log
//更友好的显示,加上行号
tail -f access.log | nl
3.3 处理日志轮转(-F 参数)
//即使文件被重命名或轮转,也能继续跟踪
tail -F /var/log/nginx/access.log
//-F 比 -f 更强大:
//- 文件被删除/重命名后会重新打开
//适用于 logrotate 等日志轮转工具
3.4 显示最后 N 个字节
//显示最后200个字节
tail -c 200 file.txt
//显示最后1KB
tail -c 1024 log.txt
3.5 从第 N 行开始显示
//从第15行开始显示(包括第15行)
tail -n +15 file.txt
//从第100行开始显示到末尾
tail -n +100 large_file.txt
3.6 组合 tail 和 head 提取中间段落
//显示第50-60行(先取前60行,再取最后11行)
head -60 file.txt | tail -11
//显示第100行到文件末尾
tail -n +100 file.txt
//显示第1-100行(排除第101行之后)
head -100 file.txt
3.7 多文件监控
//同时监控多个日志文件
tail -f error.log access.log
# 输出会标注文件来源:
# ==> error.log <==
# error message...
# ==> access.log <==
# access message...
3.8 配合 PID 自动退出
//监控日志,当进程 1234 结束时,tail 也退出
tail -f --pid=1234 app.log
4. 三个命令对比总结
特性 tee head tail
主要用途 数据分流/保存 查看文件开头 查看文件结尾
默认行数 无(处理所有输入) 10 行 10 行
是否修改文件 写入文件(不修改原内容) 只读 只读
实时监控 否 否 是(-f/-F)
常见场景 保存日志、sudo 写入 预览文件、查看配置 监控日志、查看最新数据
5. 任务:
对 login.log 执行:
1. 提取 uid(第 2 列)
2. 去重统计
3.同时输出到屏幕 并 保存到 uid_stat.log
4.只显示前 5 条
//login.log
2025-04-09 10:00:00,uid100,login_success
2025-04-09 10:01:00,uid101,login_fail
2025-04-09 10:02:00,uid100,login_success
cut -d',' -f2 login.log | sort | uniq -c | sort -nr | tee uid_stat.log | head -5
大数据排查常用:实时看日志 + 留存记录
二、SQL
511. 游戏玩法分析I

SELECT
A.player_id,
MIN(A.event_date) AS first_login
FROM
Activity A
GROUP BY
A.player_id;
分组取每组最小日期 = 首次登录日期
多字段 IN 子查询精准匹配首次登录记录
典型场景:用户首设备、首单、首次访问
1596. 每位顾客最经常订购的商品

SELECT activity_date AS login_date, COUNT(DISTINCT user_id) AS user_count
FROM Traffic
WHERE activity = 'login'
GROUP BY user_id, activity_date
HAVING MIN(activity_date) = activity_date;
先筛选 login 行为
按用户 + 日期分组,只保留最小登录日期
按日期统计当日新增登录用
1069. 产品销售分析

SELECT p.product_name, s.product_id, s.year, s.quantity, s.price
FROM Sales s
JOIN Product p ON s.product_id = p.product_id
WHERE (s.product_id, s.year) IN (
SELECT product_id, MIN(year)
FROM Sales
GROUP BY product_id
);
关联产品表获取名称
子查询找到每个产品最早销售年份
主表匹配年份,取出首年全部销售记录
三、PySpark 核心新内容
视图与函数 + 多维度排序 + 数据采样 + 性能小优化
from pyspark.sql import SparkSession
from pyspark.sql import functions as F
spark = SparkSession.builder \
.master("local[*]") \
.appName("day10") \
.getOrCreate()
data = [
(1, "click", 100, "2025-01-01"),
(1, "buy", 200, "2025-01-01"),
(2, "view", 50, "2025-01-02"),
(3, "click", 80, "2025-01-01"),
]
df = spark.createDataFrame(data, ["uid", "event", "cost", "dt"])
# ==================== 新知识点1:创建全局临时视图 ====================
df.createOrReplaceTempView("user_log")
# SQL查询
spark.sql("select uid, sum(cost) from user_log group by uid").show()
# ==================== 新知识点2:多列排序 ====================
df.orderBy(F.desc("cost"), F.asc("uid")).show()
# ==================== 新知识点3:数据采样(大数据排查用) ====================
df.sample(withReplacement=False, fraction=0.5, seed=123).show()
# ==================== 新知识点4:withColumnRenamed 重命名 ====================
df.withColumnRenamed("cost", "amount").show()
spark.stop()
createOrReplaceTempView 建临时视图
多字段组合排序
sample 数据采样
字段重命名
四、算法
LeetCode 209. 长度最小的子数组
滑动窗口 O (n) 最优解
理解左右指针收缩逻辑
对比前缀和 O (n log n) 思路
def minSubArrayLen(target, nums):
left = total = 0
min_len = float('inf')
for right in range(len(nums)):
total += nums[right]
while total >= target:
min_len = min(min_len, right-left+1)
total -= nums[left]
left += 1
return min_len if min_len != float('inf') else 0
更多推荐
所有评论(0)