文件查看与查找:head、tail、cut、find
head:查看文件开头
head 显示文件的前 N 行,默认前 10 行。
# 显示前 10 行(默认)
head file.txt
# 显示前 5 行(-n lines)
head -n 5 file.txt
# 简写
head -5 file.txt
# 显示前 100 字节(-c bytes)
head -c 100 file.txt
# 显示多个文件的前 10 行
head file1.txt file2.txt
# 从管道读取
ls /bin | head -n 20
生活类比:head 就像看书的目录和前言,快速了解文件的开头内容。
tail:查看文件末尾
tail 显示文件的最后 N 行,默认最后 10 行。最强大的是 -f 实时追踪功能。
# 显示最后 10 行(默认)
tail file.txt
# 显示最后 5 行
tail -n 5 file.txt
# 简写
tail -5 file.txt
# 显示最后 100 字节
tail -c 100 file.txt
# 从第 20 行开始显示(+ 表示从第 N 行开始)
tail -n +20 file.txt
# 实时追踪文件新增内容(-f follow)
tail -f /var/log/syslog
# 追踪并显示文件名(-F,文件被重命名或重建时重新打开)
tail -F /var/log/nginx/access.log
tail -f 的工作原理
tail -f 打开文件后保持文件描述符,当文件被追加内容时,立即输出新增部分。这是运维人员实时查看日志的必备技能。
head + tail 组合:提取中间行
# 提取第 5 到 10 行
head -n 10 file.txt | tail -n 6
# 先取前 10 行,再取后 6 行(即 5-10 行)
# 提取第 100 行
head -n 100 file.txt | tail -n 1
# 提取第 20-30 行
head -n 30 file.txt | tail -n 11
cut:按列切分
cut 按字符位置或分隔符切分每行,提取指定列。
# 按字符位置切分(-c characters)
cut -c 1-5 file.txt # 提取每行第 1-5 个字符
cut -c 1,3,5 file.txt # 提取第 1、3、5 个字符
cut -c -10 file.txt # 提取前 10 个字符
cut -c 10- file.txt # 提取第 10 个字符到行尾
# 按分隔符切分(-d delimiter,-f fields)
cut -d: -f1 /etc/passwd # 以 : 分隔,提取第 1 列(用户名)
cut -d: -f1,3 /etc/passwd # 提取第 1 和第 3 列
cut -d: -f1-3 /etc/passwd # 提取第 1-3 列
cut -d' ' -f2 file.txt # 以空格分隔,提取第 2 列
# 从管道读取
ps aux | cut -c 1-10 # 提取每行前 10 个字符
cut vs awk 对比
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 固定宽度文件 | cut -c | 简单直接 |
| 分隔符切分,简单提取 | cut -d -f | 语法简洁 |
| 复杂条件、计算、格式化 | awk | 功能强大 |
| 正则分隔符 | awk -F | 支持正则 |
find:文件查找
find 是 Linux 最强大的文件查找工具,支持按名称、类型、大小、时间、权限等多种条件查找。
基础用法
# 在当前目录及子目录查找名为 file.txt 的文件
find . -name "file.txt"
# 查找所有 .txt 文件(通配符需加引号)
find . -name "*.txt"
# 忽略大小写(-iname)
find . -iname "*.TXT"
# 查找目录(-type d)
find . -type d -name "logs"
# 查找普通文件(-type f)
find . -type f -name "*.log"
# 查找符号链接(-type l)
find . -type l
按大小查找
# 查找大于 100M 的文件
find . -size +100M
# 查找小于 1K 的文件
find . -size -1k
# 查找恰好 10M 的文件
find . -size 10M
# 查找大于 1G 的文件
find . -size +1G
大小单位:
b= 512 字节块(默认)c= 字节k= KBM= MBG= GB
按时间查找
# 查找 7 天内修改过的文件(-mtime modify-time)
find . -mtime -7
# 查找 7 天前修改过的文件
find . -mtime +7
# 查找恰好 3 天前修改的文件
find . -mtime 3
# 查找 1 小时内访问过的文件(-atime access-time)
find . -atime -1
# 查找 30 分钟内修改过的文件(-mmin)
find . -mmin -30
| 时间选项 | 含义 |
|---|---|
-mtime n | 修改时间(天) |
-atime n | 访问时间(天) |
-ctime n | 状态改变时间(天) |
-mmin n | 修改时间(分钟) |
-amin n | 访问时间(分钟) |
按权限查找
# 查找权限为 644 的文件
find . -perm 644
# 查找所有者可执行的文件
find . -perm /u=x
# 查找权限至少为 755 的文件
find . -perm -755
执行操作(-exec)
# 查找并删除(⚠️ 谨慎使用)
find . -name "*.tmp" -exec rm {} \;
# 查找并显示详细信息
find . -name "*.log" -exec ls -lh {} \;
# 查找并复制到目录
find . -name "*.conf" -exec cp {} /backup/ \;
# 使用 + 代替 \; 更高效(批量传参)
find . -name "*.txt" -exec cat {} +
# 查找并执行命令(-ok 会每次确认)
find . -name "*.old" -ok rm {} \;
逻辑组合
# AND(默认)
find . -name "*.txt" -size +1M
# OR(-o)
find . -name "*.txt" -o -name "*.log"
# NOT(!)
find . ! -name "*.txt"
# 括号需要转义
find . \( -name "*.txt" -o -name "*.log" \) -size +1M
综合实战
场景 1:清理日志文件
# 查找 30 天前的日志并删除
find /var/log -name "*.log" -mtime +30 -exec rm {} \;
# 查找 7 天前的日志并压缩
find /var/log -name "*.log" -mtime +7 -exec gzip {} \;
场景 2:查找大文件
# 查找 /home 下大于 100M 的文件
find /home -type f -size +100M -exec ls -lh {} \;
# 查找当前目录下最大的 10 个文件
find . -type f -exec ls -lh {} + | sort -k5 -rh | head -n 10
场景 3:批量修改权限
# 查找所有 .sh 文件并添加执行权限
find . -name "*.sh" -exec chmod +x {} \;
# 查找所有目录并设置 755
find . -type d -exec chmod 755 {} \;
# 查找所有文件并设置 644
find . -type f -exec chmod 644 {} \;
本篇小结
head:查看文件开头,-n 5前 5 行,-c 100前 100 字节tail:查看文件末尾,-n 5后 5 行,-f实时追踪日志,-F文件重建时重新打开head -n 10 | tail -n 5:提取中间行(第 6-10 行)cut:按字符位置(-c)或分隔符(-d -f)切分列find:按名称(-name)、类型(-type)、大小(-size)、时间(-mtime)、权限(-perm)查找find ... -exec cmd {} \;:对查找结果执行命令
动手实践
head/tail 练习:
head -n 5 /etc/passwd tail -n 5 /etc/passwd head -n 10 /etc/passwd | tail -n 5 # 第 6-10 行 tail -f /var/log/syslog # 实时追踪(按 Ctrl+C 退出)cut 练习:
cut -d: -f1 /etc/passwd # 用户名 cut -d: -f1,3,7 /etc/passwd # 用户名、UID、Shell ps aux | cut -c 1-15 # 提取前 15 个字符find 基础练习:
find /bin -type f -name "a*" # /bin 下以 a 开头的文件 find ~ -type f -size +10M # 家目录下大于 10M 的文件 find /var/log -name "*.log" -mtime +7 # 7 天前的日志find + exec 练习:
find . -name "*.txt" -exec ls -lh {} \; find . -type d -name "test*"综合练习:
# 查找当前目录下所有 .md 文件,显示前 3 行 find . -name "*.md" -exec head -n 3 {} \;思考:
tail -f和tail -F有什么区别?如果日志文件被日志轮转(logrotate)重命名为access.log.1并新建了access.log,哪个选项能继续追踪新的日志文件?