欢迎光临
我们一直在努力

Linux 操作命令完全指南

Linux 操作命令完全指南

环境:华为云 ECS ecs-b97e-0001(2vCPU/4GiB/ac9.large.2) | Ubuntu 24.04 LTS | Linux 6.8.0 | Git 2.43.0 所有输出均为真实服务器终端输出 | 创建日期:2026-06-15


目录

  • 实验一:ls / cd / pwd
  • 实验二:mkdir / rm / mv / cp / cat / nl
  • 实验三:more / less / head / tail
  • 实验四:which / whereis / locate
  • 实验五:find / xargs
  • 实验六:wc / grep / 正则表达式
  • 实验七:cut / paste / tr
  • 实验八:sort / uniq / join
  • 实验九:comm / diff / patch
  • 实验十:df / du / time
  • 命令速查表

  • 实验一:ls / cd / pwd

    1.1 知识点概览

    ┌─────────────────────────────────────────────────┐
    │ Linux 目录导航三剑客 │
    ├──────────┬──────────┬───────────────────────────┤
    │ pwd │ Print │ 显示当前工作目录绝对路径 │
    │ │ Working │ -P: 显示物理路径(无视符号链) │
    │ │ Directory│ -L: 显示逻辑路径(默认) │
    ├──────────┼──────────┼───────────────────────────┤
    │ cd │ Change │ 切换工作目录 │
    │ │ Directory│ cd – : 回到上次目录 │
    │ │ │ cd ~ : 回到HOME │
    │ │ │ cd / : 到根目录 │
    ├──────────┼──────────┼───────────────────────────┤
    │ ls │ List │ 列出目录内容 │
    │ │ │ -l: 长格式(权限/大小/时间) │
    │ │ │ -a: 显示隐藏文件 │
    │ │ │ -h: 人类可读大小 │
    │ │ │ -R: 递归列出 │
    │ │ │ -t: 按时间排序 │
    │ │ │ -S: 按大小排序 │
    │ │ │ -i: 显示inode号 │
    │ │ │ -d: 只显示目录本身 │
    └──────────┴──────────┴───────────────────────────┘

    1.2 pwd — 显示当前工作目录

    $ pwd
    /tmp/cmd-lab-01

    说明:pwd 是最简单的命令,没有任何选项,直接输出当前所在目录的绝对路径。始终从根目录 / 开始。

    1.3 cd — 切换目录

    # 进入子目录
    $ cd dir1 && pwd
    /tmp/cmd-lab-01/dir1

    # cd .. 返回上级
    $ cd .. && pwd
    /tmp/cmd-lab-01

    # cd – 回到上次所在目录
    $ cd dir2 && pwd
    /tmp/cmd-lab-01/dir2
    $ cd – && pwd
    /tmp/cmd-lab-01

    # cd ~ 回到家目录
    $ cd ~ && pwd
    /root

    # 从根目录导航回来
    $ cd / && ls -d tmp
    tmp
    $ cd /tmp/cmd-lab-01 && pwd
    /tmp/cmd-lab-01

    快捷方式含义说明
    cd – 回到上一次目录 使用 $OLDPWD 环境变量
    cd ~ 或 cd 回到 HOME 目录 $HOME 变量指定
    cd .. 上级目录 每个目录都有 . 和 ..
    cd / 根目录 文件系统顶层

    1.4 ls — 列出目录内容

    首先创建测试环境:

    $ mkdir -p dir1 dir2 dir3
    $ touch file1.txt file2.txt file3.log .hidden_file script.sh
    $ ln -s file1.txt link_to_file1

    ls 无参数:仅显示非隐藏文件名

    $ ls
    dir1 dir2 dir3 file1.txt file2.txt file3.log link_to_file1 script.sh

    ls -l:长格式(Long format),显示权限/硬链接数/所有者/组/大小/修改时间/文件名

    $ ls -l
    total 12
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir2
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir3
    -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh

    ls 权限字段解读(以 -rw-r–r– 为例):

    – rw- r– r–
    │ │ │ └─ 其他用户权限 (r=读, – =无)
    │ │ └─ 组权限
    │ └─ 所有者权限
    └─ 文件类型 (-=普通文件, d=目录, l=符号链接)

    ls -a:显示隐藏文件(以 . 开头)

    $ ls -a
    . .. dir1 dir2 dir3 file1.txt file2.txt file3.log .hidden_file link_to_file1 script.sh

    关键发现:.hidden_file 在 ls 中不可见,在 ls -a 中出现。

    ls -lh:人类可读的大小格式

    $ ls -lh
    total 12K
    drwxr-xr-x 2 root root 4.0K Jun 15 22:15 dir1
    drwxr-xr-x 2 root root 4.0K Jun 15 22:15 dir2
    drwxr-xr-x 2 root root 4.0K Jun 15 22:15 dir3
    -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh

    ls -R:递归列出子目录

    $ ls -R
    .:
    dir1 dir2 dir3 file1.txt file2.txt file3.log link_to_file1 script.sh

    ./dir1:

    ./dir2:

    ./dir3:

    ls -lt:按修改时间排序(最新在前)

    $ ls -lt
    total 12
    lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir2
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir3
    -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh

    ls -ltr:按时间逆序(最旧在前)— 运维常用,最新文件在最后一行

    $ ls -ltr
    total 12
    -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh
    -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir3
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir2
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1
    lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt

    ls -lS:按文件大小排序(大文件在前)

    $ ls -lS
    total 12
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir2
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir3
    lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh

    ls -d:只显示目录自身,不列出其内容

    $ ls -ld dir1
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1

    ls -i:显示 inode 号

    $ ls -li
    total 12
    395791 drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir1
    395793 drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir2
    395794 drwxr-xr-x 2 root root 4096 Jun 15 22:15 dir3
    395795 -rw-r–r– 1 root root 0 Jun 15 22:15 file1.txt
    395796 -rw-r–r– 1 root root 0 Jun 15 22:15 file2.txt
    395797 -rw-r–r– 1 root root 0 Jun 15 22:15 file3.log
    395800 lrwxrwxrwx 1 root root 9 Jun 15 22:15 link_to_file1 –> file1.txt
    395799 -rw-r–r– 1 root root 0 Jun 15 22:15 script.sh

    inode(索引节点):每个文件在文件系统中的唯一编号。link_to_file1 -> file1.txt 的 inode 号(395800)与 file1.txt(395795)不同,因为符号链接有自己的 inode。

    1.5 ls 常用组合速查

    命令效果使用场景
    ls -la 全部文件长格式 最常用,查看所有文件详情
    ls -lh 人类可读大小 快速判断大文件
    ls -ltr 按时间逆序 查看最近修改的文件
    ls -lS 按大小排序 排查磁盘占用
    ls -R 递归列出 了解目录结构
    ls -d */ 仅显示目录 只看子目录

    实验二:mkdir / rm / mv / cp / cat / nl

    2.1 知识点概览

    ┌────────────────────────────────────────────────────────────┐
    │ 文件与目录操作六命令 │
    ├──────────┬─────────┬───────────────────────────────────────┤
    │ mkdir │ 创建 │ -p: 递归创建 -m: 指定权限 -v: 详细 │
    │ rm │ 删除 │ -r: 递归 -f: 强制 -i: 确认 -v: 详细│
    │ mv │ 移动/ │ 同分区内移动=改inode指针(快) │
    │ │ 重命名 │ 跨分区移动=复制+删除(慢) │
    │ cp │ 复制 │ -r: 递归 -p: 保留属性 -u: 增量 │
    │ cat │ 查看 │ -n: 所有行号 -b: 非空行号 │
    │ │ 合并 │ -s: 压缩连续空行 │
    │ nl │ 行号 │ -b a/t: 所有/非空 -n ln/rn: 对齐 │
    └──────────┴─────────┴───────────────────────────────────────┘

    2.2 mkdir — 创建目录

    # 递归创建多层目录(-p 不会因中间目录不存在而报错)
    $ mkdir -p a/b/c/d
    $ ls -R a
    a:
    b

    a/b:
    c

    a/b/c:
    d

    a/b/c/d:

    # 创建时指定权限
    $ mkdir -m 755 public_dir
    $ ls -ld public_dir
    drwxr-xr-x 2 root root 4096 Jun 15 22:15 public_dir

    选项含义示例
    -p 创建父目录,已存在不报错 mkdir -p /var/log/myapp/2026/06
    -m 指定权限模式(chmod风格) mkdir -m 755 public
    -v 显示创建过程 mkdir -v dir1 dir2

    2.3 rm — 删除文件/目录

    # 交互式删除(-i 每次确认)
    $ touch delete_me.txt
    $ rm -iv delete_me.txt
    rm: remove regular empty file 'delete_me.txt'? removed 'delete_me.txt'

    # 递归删除目录树(-r 递归,-v 详细)
    $ mkdir -p test_rm/sub && touch test_rm/sub/file.txt
    $ rm -rv test_rm
    removed 'test_rm/sub/file.txt'
    removed directory 'test_rm/sub'
    removed directory 'test_rm'

    选项含义⚠️ 风险
    -r 递归删除目录及内容 高危!删除前用 ls -R 确认
    -f 强制删除,不提示 极高危! rm -rf / 会毁系统
    -i 逐个确认 建议设置别名 alias rm='rm -i'
    -v 显示删除过程 便于审计

    踩坑记录:rm -rf * 不会删除隐藏文件(. 开头),需用 rm -rf .* 或 rm -rf * .*。

    2.4 mv — 移动/重命名

    # 重命名(同一目录下移动=改名)
    $ touch oldname.txt
    $ mv oldname.txt newname.txt
    $ ls *.txt
    newname.txt

    # 移动到子目录
    $ mkdir dest_dir
    $ mv newname.txt dest_dir/
    $ ls dest_dir/
    newname.txt

    原理:同一文件系统内,mv 只修改目录条目(dirent)中的文件名指针,不复制数据块。因此即使移动 GB 级文件也是瞬间完成。

    2.5 cp — 复制文件/目录

    # 基本复制
    $ echo "hello copy" > source.txt
    $ cp source.txt copy1.txt
    $ ls -l source.txt copy1.txt
    -rw-r–r– 1 root root 11 Jun 15 22:15 copy1.txt
    -rw-r–r– 1 root root 11 Jun 15 22:15 source.txt

    # 递归复制目录
    $ mkdir src_dir && touch src_dir/a.txt src_dir/b.txt
    $ cp -r src_dir dest_copy
    $ ls -R dest_copy
    dest_copy:
    a.txt b.txt

    # 保留源文件属性(-p = preserve)
    $ cp -p source.txt copy_preserve.txt
    $ ls -l source.txt copy_preserve.txt
    -rw-r–r– 1 root root 11 Jun 15 22:15 copy_preserve.txt
    -rw-r–r– 1 root root 11 Jun 15 22:15 source.txt

    # 增量复制(-u = update,源更新时才复制)
    $ echo "newer" > source.txt
    $ cp -uv source.txt copy1.txt
    'source.txt' –> 'copy1.txt'

    选项含义典型场景
    -r 递归复制目录 cp -r project/ backup/
    -p 保留权限/时间戳/所有者 备份时保持元数据
    -u 仅当源比目标新时复制 增量备份
    -a 归档模式(-dR –preserve=all) 完整备份
    -v 显示复制过程 大量文件时看进度

    2.6 cat — 查看与合并文件

    # 查看文件内容
    $ echo "newer" > source.txt
    $ cat source.txt
    newer

    # -n 显示所有行号
    $ printf "line1\\nline2\\nline3" > numbered.txt
    $ cat -n numbered.txt
    1line1
    2line2
    3line3

    # -b 仅非空行加行号
    $ printf "line1\\n\\nline3" > with_blank.txt
    $ cat -b with_blank.txt
    1line1

    2line3

    # -s 压缩连续空行(Squeeze)
    $ cat -s with_blank.txt
    line1

    line3

    # 合并多个文件
    $ echo "file A" > fa.txt && echo "file B" > fb.txt
    $ cat fa.txt fb.txt > merged.txt
    $ cat merged.txt
    file A
    file B

    选项含义备注
    -n 所有行加行号(含空行) 从1开始
    -b 仅非空行加行号 与 -n 互斥
    -s 压缩连续空行为一行 清理冗余空行
    -A 显示所有控制字符 $ 表示行尾,^I 表示Tab
    -T Tab 显示为 ^I 区分Tab和空格

    2.7 nl — 行号工具(比 cat -n 更灵活)

    # 基本用法(等同 cat -n)
    $ nl numbered.txt
    1line1
    2line2
    3line3

    # -b a 所有行都编号
    $ nl -b a with_blank.txt
    1line1
    2
    3line3

    # -b t 仅非空行编号(默认行为)
    $ nl -b t with_blank.txt
    1line1

    2line3

    # -n ln 左对齐编号
    $ nl -n ln numbered.txt
    1 line1
    2 line2
    3 line3

    # -n rn 右对齐编号(默认)
    $ nl -n rn numbered.txt
    1line1
    2line2
    3line3

    选项含义
    -b a 所有行编号
    -b t 仅非空行编号(默认)
    -n ln 编号左对齐
    -n rn 编号右对齐(默认)
    -n rz 编号右对齐且补零

    实验三:more / less / head / tail

    3.1 知识点概览

    ┌───────────────────────────────────────────────────────────────┐
    │ 文本浏览四命令 │
    ├──────────┬────────┬──────────────────────────────────────────┤
    │ head │ 看前面 │ -n N: 前N行 -n -N: 除最后N行外的全部 │
    │ │ │ -c N: 前N字节 │
    ├──────────┼────────┼──────────────────────────────────────────┤
    │ tail │ 看后面 │ -n N: 后N行 -n +N: 从第N行开始 │
    │ │ │ -f: 实时跟踪(日志监控核心) │
    ├──────────┼────────┼──────────────────────────────────────────┤
    │ more │ 分页 │ 早期分页器,只能向下翻 │
    ├──────────┼────────┼──────────────────────────────────────────┤
    │ less │ 分页+ │ 现代分页器,支持前后翻页、搜索高亮 │
    │ │ │ 快捷键: j/k上下 f/b翻页 /搜索 q退出 │
    └──────────┴────────┴──────────────────────────────────────────┘

    首先创建50行测试文件:

    $ for i in $(seq 1 50); do echo "Line $i: This is a test line for pagination commands demonstration"; done > longfile.txt
    $ wc -l longfile.txt
    50 longfile.txt

    3.2 head — 查看文件头部

    # 默认显示前10行
    $ head longfile.txt
    Line 1: This is a test line for pagination commands demonstration
    Line 2: This is a test line for pagination commands demonstration
    Line 3: This is a test line for pagination commands demonstration
    Line 4: This is a test line for pagination commands demonstration
    Line 5: This is a test line for pagination commands demonstration
    Line 6: This is a test line for pagination commands demonstration
    Line 7: This is a test line for pagination commands demonstration
    Line 8: This is a test line for pagination commands demonstration
    Line 9: This is a test line for pagination commands demonstration
    Line 10: This is a test line for pagination commands demonstration

    # 显示前3行
    $ head -n 3 longfile.txt
    Line 1: This is a test line for pagination commands demonstration
    Line 2: This is a test line for pagination commands demonstration
    Line 3: This is a test line for pagination commands demonstration

    # 截取前50字节
    $ head -c 50 longfile.txt
    Line 1: This is a test line for pagination command

    # 显示除了最后5行之外的全部(共50行,显示1~45行)
    $ head -n 45 longfile.txt | tail -3
    Line 43: This is a test line for pagination commands demonstration
    Line 44: This is a test line for pagination commands demonstration
    Line 45: This is a test line for pagination commands demonstration

    3.3 tail — 查看文件尾部

    # 默认后10行
    $ tail longfile.txt
    Line 41: This is a test line for pagination commands demonstration
    Line 42: This is a test line for pagination commands demonstration
    ...
    Line 50: This is a test line for pagination commands demonstration

    # 最后3行
    $ tail -n 3 longfile.txt
    Line 48: This is a test line for pagination commands demonstration
    Line 49: This is a test line for pagination commands demonstration
    Line 50: This is a test line for pagination commands demonstration

    # 从第46行开始到末尾
    $ tail -n +46 longfile.txt
    Line 46: This is a test line for pagination commands demonstration
    Line 47: This is a test line for pagination commands demonstration
    Line 48: This is a test line for pagination commands demonstration
    Line 49: This is a test line for pagination commands demonstration
    Line 50: This is a test line for pagination commands demonstration

    # 截取最后50字节
    $ tail -c 50 longfile.txt
    a test line for pagination commands demonstration

    tail -f 实时监控:tail -f /var/log/syslog — 文件被追加时自动显示新内容,按 Ctrl+C 退出。运维最常用命令之一。

    3.4 more — 分页浏览(早期工具)

    快捷键:
    Space → 下一页
    b → 上一页
    Enter → 下一行
    q → 退出
    /pattern → 搜索
    = → 显示当前行号

    3.5 less — 现代分页器

    快捷键(比 more 强大得多):
    j/k → 上/下一行
    f/b → 前/后翻页
    G/g → 文件尾/头
    /pattern → 向下搜索
    ?pattern → 向上搜索
    n/N → 下一个/上一个搜索结果
    q → 退出
    -N → 显示行号
    -S → 不折行显示

    重要:less 是 Linux 哲学 “less is more” 的体现 — 比 more 更强大。它不会一次性读取整个文件到内存,大文件也能流畅浏览。

    3.6 head / tail 日志监控典型组合

    # 实时监控日志(最常用)
    tail -f /var/log/syslog

    # 查看最近100行中的错误
    tail -n 100 /var/log/syslog | grep -i error

    # 查看文件第11-20行(head+tail组合)
    head -n 20 file.txt | tail -n 10

    # 截取第100行到末尾
    tail -n +100 file.txt


    实验四:which / whereis / locate

    4.1 知识点概览

    ┌───────────────────────────────────────────────────────────────┐
    │ 命令定位三工具 │
    ├──────────┬──────────┬─────────────────────────────────────────┤
    │ which │ PATH搜索 │ 查找可执行文件的完整路径 │
    │ │ │ 仅对PATH中的外部命令有效 │
    │ │ │ 内建命令/别名 用 type 替代 │
    ├──────────┼──────────┼─────────────────────────────────────────┤
    │ whereis │ 标准位置 │ 查找二进制+手册+源码 │
    │ │ │ 搜索范围固定: /bin,/usr/bin,/usr/man … │
    ├──────────┼──────────┼─────────────────────────────────────────┤
    │ locate │ 全盘搜索 │ 基于数据库索引,速度极快 │
    │ │ │ 需要 updatedb 先构建索引 │
    │ │ │ 本机未安装(mlocate包) │
    └──────────┴──────────┴─────────────────────────────────────────┘

    4.2 which — 查找 PATH 中的可执行文件

    $ which python3
    /usr/bin/python3

    $ which git
    /usr/bin/git

    $ which vim curl ls cp
    /usr/bin/vim
    /usr/bin/curl
    /usr/bin/ls
    /usr/bin/cp

    # -a 显示所有匹配(PATH 中可能有多个同名文件)
    $ which -a python3
    /usr/bin/python3
    /bin/python3

    # 内建命令 which 无法定位
    $ which cd
    $ which echo
    /usr/bin/echo ← 该系统有 echo 的外部版本
    $ which pwd
    /usr/bin/pwd ← 该系统有 pwd 的外部版本

    注意:which cd 无输出 → cd 是 shell 内建命令。用 type 更准确:

    $ type cd
    cd is a shell builtin

    $ type echo
    echo is a shell builtin

    $ type ls
    ls is /usr/bin/ls

    $ type git
    git is /usr/bin/git

    4.3 whereis — 查找二进制+手册+源码

    $ whereis python3
    python3: /usr/bin/python3 /usr/lib/python3 /etc/python3 /usr/share/python3 /usr/share/man/man1/python3.1.gz

    $ whereis git
    git: /usr/bin/git /usr/share/man/man1/git.1.gz

    $ whereis bash
    bash: /usr/bin/bash /usr/share/man/man1/bash.1.gz

    # 仅查二进制 (-b)
    $ whereis -b python3
    python3: /usr/bin/python3 /usr/lib/python3 /etc/python3 /usr/share/python3

    # 仅查手册 (-m)
    $ whereis -m python3
    python3: /usr/share/man/man1/python3.1.gz

    # 仅查源码 (-s)
    $ whereis -s python3
    python3:

    选项含义
    -b 只搜索二进制文件
    -m 只搜索手册页
    -s 只搜索源码文件

    4.4 locate — 全盘文件名搜索(需要索引)

    # 本机未安装 mlocate
    $ locate –version
    bash: locate: command not found

    # 安装方式
    $ apt-get install -y mlocate
    $ updatedb # 构建索引数据库
    $ locate passwd | head -5
    # … 搜索结果

    4.5 三工具对比

    维度whichwhereislocate
    搜索范围 PATH环境变量 标准系统目录 全盘(由updatedb索引)
    搜索内容 可执行文件 二进制+手册+源码 所有文件名
    速度 极快 快 极快(查数据库)
    实时性 实时 实时 非实时(需updatedb更新)
    内建命令 不支持 不支持 不支持
    典型场景 确认用的是哪个版本 查手册位置 忘记文件放哪了

    实验五:find / xargs

    5.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ find — Linux 最强文件搜索工具 │
    ├──────────────┬───────────────────────────────────────────────┤
    │ 搜索条件 │ -name -type -size -mtime -perm -user -group │
    │ 逻辑运算 │ -a(与) -o(或) -not/!(取反) │
    │ 执行动作 │ -exec -print -delete -ok │
    │ 深度控制 │ -maxdepth -mindepth │
    ├──────────────┼───────────────────────────────────────────────┤
    │ xargs │ 将标准输入转为命令行参数 │
    │ │ -n: 每批参数数量 -I: 占位符替换 │
    │ │ -p: 执行前确认 -0: NULL分隔(防空格问题) │
    └──────────────┴───────────────────────────────────────────────┘

    首先创建测试文件结构(Java项目模拟):

    $ mkdir -p src/main/java/com/example src/test/java/com/example src/main/resources logs/2026/06
    $ touch src/main/java/com/example/App.java src/main/java/com/example/Utils.java
    $ touch src/test/java/com/example/AppTest.java src/main/resources/application.yml
    $ touch logs/2026/06/app.log logs/2026/06/error.log .gitignore README.md
    $ echo "Hello World" > src/main/resources/application.yml
    $ echo "ERROR: something wrong" > logs/2026/06/error.log
    $ echo "INFO: app started" > logs/2026/06/app.log

    5.2 find 按名称查找

    $ find . -name "*.java"
    ./src/test/java/com/example/AppTest.java
    ./src/main/java/com/example/App.java
    ./src/main/java/com/example/Utils.java

    5.3 find 按类型查找

    $ find . -type d -name "example"
    ./src/test/java/com/example
    ./src/main/java/com/example

    类型字符含义
    f 普通文件(regular file)
    d 目录(directory)
    l 符号链接(symbolic link)
    b 块设备(block device)
    c 字符设备(character device)
    s 套接字(socket)
    p 命名管道(FIFO)

    5.4 find 按大小查找

    $ find . -type f -size +0c
    ./src/main/resources/application.yml
    ./logs/2026/06/error.log
    ./logs/2026/06/app.log

    大小单位:c=字节, k=KB, M=MB, G=GB + = 大于,- = 小于,无符号 = 精确匹配

    5.5 find 按时间和权限

    # 最近1小时内修改的文件
    $ find . -type f -mmin -60 | sort
    ./.gitignore
    ./README.md
    ./logs/2026/06/app.log
    ./logs/2026/06/error.log
    ./src/main/java/com/example/App.java
    ./src/main/java/com/example/Utils.java
    ./src/main/resources/application.yml
    ./src/test/java/com/example/AppTest.java

    # 按权限查找
    $ find . -type f -perm 644
    ./.gitignore
    ./README.md
    ./src/main/java/com/example/App.java
    ./src/main/java/com/example/Utils.java
    ./src/main/resources/application.yml
    ./src/test/java/com/example/AppTest.java
    ./logs/2026/06/app.log
    ./logs/2026/06/error.log

    时间选项含义单位
    -mtime N 修改时间=N天前 天
    -mmin N 修改时间=N分钟前 分钟
    -atime N 访问时间 天
    -ctime N 状态改变时间 天

    5.6 find 深度控制

    $ find . -maxdepth 2 -type d
    .
    ./src
    ./src/test
    ./src/main
    ./logs
    ./logs/2026

    5.7 find 组合条件

    # 查找所有 .log 或 .yml 文件(-o = OR)
    $ find . \\( -name "*.log" -o -name "*.yml" \\) | sort
    ./logs/2026/06/app.log
    ./logs/2026/06/error.log
    ./src/main/resources/application.yml

    # 取反:查找空文件
    $ touch empty_file.txt
    $ find . -type f -empty
    ./.gitignore
    ./README.md
    ./src/main/java/com/example/App.java
    ./src/main/java/com/example/Utils.java
    ./src/test/java/com/example/AppTest.java
    ./empty_file.txt

    5.8 find 执行命令

    # -exec 方式:每个文件独立执行
    $ find . -name "*.java" -exec wc -l {} \\;
    0 ./src/test/java/com/example/AppTest.java
    0 ./src/main/java/com/example/App.java
    0 ./src/main/java/com/example/Utils.java

    5.9 find + xargs 组合(更高效)

    # xargs 方式:批量传递参数,少次调用
    $ find . -name "*.java" | xargs wc -l
    0 ./src/test/java/com/example/AppTest.java
    0 ./src/main/java/com/example/App.java
    0 ./src/main/java/com/example/Utils.java
    0 total

    -exec vs xargs:-exec 每个文件调一次命令(慢),xargs 批量调用(快)。但文件名含空格时 xargs 可能出错,用 xargs -0 + find -print0 解决。

    5.10 xargs 其他用法

    # -n 2:每次传2个参数
    $ echo "one two three four five" | xargs -n 2 echo
    one two
    three four
    five

    # -I {}:占位符替换
    $ find . -name "*.java" | xargs -I {} echo "Processing: {}"
    Processing: ./src/test/java/com/example/AppTest.java
    Processing: ./src/main/java/com/example/App.java
    Processing: ./src/main/java/com/example/Utils.java

    # 删除文件
    $ find . -name "empty_file.txt" | xargs rm -v
    removed './empty_file.txt'

    5.11 find 常用实战组合

    # 查找并删除30天前的日志
    find /var/log -name "*.log" -mtime +30 -exec rm {} \\;

    # 查找大文件(>100MB)
    find / -type f -size +100M -exec ls -lh {} \\;

    # 查找空目录并删除
    find . -type d -empty -delete

    # 批量修改文件权限
    find . -name "*.sh" -exec chmod +x {} \\;

    # 查找最近修改的5个文件
    find . -type f -printf '%T@ %p\\n' | sort -rn | head -5


    实验六:wc / grep / 正则表达式

    6.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ 文本统计 + 搜索 + 正则 │
    ├──────────┬─────────┬─────────────────────────────────────────┤
    │ wc │ 统计 │ -l:行 -c:字节 -m:字符 -w:单词 -L:最长行 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ grep │ 搜索 │ -i:忽略大小写 -v:反向 -n:行号 │
    │ │ │ -c:计数 -w:全词 -r:递归 -l:文件名 │
    │ │ │ -A/B/C:上下文 -E:扩展正则 -o:仅匹配 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ 正则 │ 模式 │ ^行首 $行尾 .任意 []字符类 *0~N次 │
    │ │ │ + 1~N次 ? 0/1次 {N}精确 {N,M}范围 │
    └──────────┴─────────┴─────────────────────────────────────────┘

    创建测试数据:

    $ printf "apple\\nbanana\\nApple\\nBANANA\\nAPPLE\\napricot\\navocado\\nblackberry\\nblueberry\\ncranberry" > fruits.txt
    $ printf "user001:alice:admin\\nuser002:bob:user\\nuser003:charlie:admin\\nuser004:david:user\\nuser005:eve:admin\\nuser006:frank:guest" > users.txt
    $ printf "192.168.1.1 – GET /index.html 200\\n192.168.1.2 – POST /api/login 401\\n10.0.0.1 – GET /api/users 200\\n192.168.1.1 – GET /images/logo.png 304\\n10.0.0.2 – DELETE /api/session 500\\n192.168.1.3 – PUT /api/profile 200\\n10.0.0.1 – GET /api/data 200\\n192.168.1.4 – POST /api/upload 413" > access.log

    6.2 wc — 文本统计

    # 行数统计
    $ wc -l fruits.txt users.txt
    9 fruits.txt
    5 users.txt
    14 total

    # 多维度统计
    $ wc -c fruits.txt # 字节数
    78 fruits.txt

    $ wc -m fruits.txt # 字符数
    78 fruits.txt

    $ wc -w fruits.txt # 单词数
    10 fruits.txt

    $ wc -L fruits.txt # 最长行字符数
    10 fruits.txt

    选项含义示例
    -l 行数 wc -l file.txt
    -c 字节数 wc -c file.txt
    -m 字符数(多字节字符正确计数) wc -m file.txt
    -w 单词数 wc -w file.txt
    -L 最长行的字符数 wc -L file.txt

    6.3 grep — 文本搜索

    # 基本搜索(区分大小写)
    $ grep "apple" fruits.txt
    apple

    # -i 忽略大小写
    $ grep -i "apple" fruits.txt
    apple
    Apple
    APPLE

    # -v 反向匹配(排除)
    $ grep -v "berry" fruits.txt
    apple
    banana
    Apple
    BANANA
    APPLE
    apricot
    avocado

    # -c 计数
    $ grep -c "admin" users.txt
    3

    # -w 全词匹配(不是子串)
    $ grep -w "apple" fruits.txt
    apple

    $ grep -w "app" fruits.txt
    (no exact match)

    6.4 grep 上下文控制

    # -n 显示行号
    $ grep -n "GET" access.log
    1:192.168.1.1 – GET /index.html 200
    3:10.0.0.1 – GET /api/users 200
    4:192.168.1.1 – GET /images/logo.png 304
    7:10.0.0.1 – GET /api/data 200

    # -A 2:显示匹配行及之后2行
    $ grep -A 2 "192.168.1.1" access.log
    192.168.1.1 – GET /index.html 200
    192.168.1.2 – POST /api/login 401
    10.0.0.1 – GET /api/users 200
    192.168.1.1 – GET /images/logo.png 304
    10.0.0.2 – DELETE /api/session 500
    192.168.1.3 – PUT /api/profile 200

    # -B 2:显示匹配行及之前2行
    $ grep -B 2 "500" access.log
    10.0.0.1 – GET /api/users 200
    192.168.1.1 – GET /images/logo.png 304
    10.0.0.2 – DELETE /api/session 500

    # -C 1:显示匹配行前后各1行
    $ grep -C 1 "401" access.log
    192.168.1.1 – GET /index.html 200
    192.168.1.2 – POST /api/login 401
    10.0.0.1 – GET /api/users 200

    6.5 grep 递归与文件搜索

    # -r 递归搜索目录
    $ grep -r "ERROR" /tmp/cmd-lab-05/
    /tmp/cmd-lab-05/logs/2026/06/error.log:ERROR: something wrong

    # -l 仅显示含匹配的文件名
    $ grep -rl "Hello" /tmp/cmd-lab-05/
    /tmp/cmd-lab-05/src/main/resources/application.yml

    6.6 grep 正则表达式

    # 行尾锚定:以 200 结尾的行
    $ grep -E "200$" access.log
    192.168.1.1 – GET /index.html 200
    10.0.0.1 – GET /api/users 200
    192.168.1.3 – PUT /api/profile 200
    10.0.0.1 – GET /api/data 200

    # 行首锚定:以 192 开头的行(内网IP)
    $ grep "^192" access.log
    192.168.1.1 – GET /index.html 200
    192.168.1.2 – POST /api/login 401
    192.168.1.1 – GET /images/logo.png 304
    192.168.1.3 – PUT /api/profile 200
    192.168.1.4 – POST /api/upload 413

    # IP 地址匹配
    $ grep -E "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" access.log | head -3
    192.168.1.1 – GET /index.html 200
    192.168.1.2 – POST /api/login 401
    10.0.0.1 – GET /api/users 200

    6.7 grep 管道组合(最常用)

    # 统计成功(200)且为GET请求的数量
    $ grep "200" access.log | grep "GET" | wc -l
    3

    6.8 正则表达式速查

    ┌─────────────────────────────────────────────────────┐
    │ 基础正则 (BRE — grep 默认) │
    │ ^ 行首锚定 $ 行尾锚定 │
    │ . 任意单字符 * 前字符0~N次 │
    │ [] 字符类 [^] 否定字符类 │
    │ \\ 转义符 \\< \\> 词边界 │
    ├─────────────────────────────────────────────────────┤
    │ 扩展正则 (ERE — grep -E / egrep) │
    │ + 前字符1~N次 ? 前字符0/1次 │
    │ {N} 精确N次 {N,} 至少N次 │
    │ {N,M} N~M次 | 或(alternation) │
    │ () 分组 \\1 反向引用 │
    └─────────────────────────────────────────────────────┘


    实验七:cut / paste / tr

    7.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ 列处理 + 合并 + 字符转换 │
    ├──────────┬─────────┬─────────────────────────────────────────┤
    │ cut │ 列截取 │ -f:按字段(需-d分隔符) -c:按字符位置 │
    │ │ │ -b:按字节位置 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ paste │ 行合并 │ 横向:多文件逐行拼接 │
    │ │ │ -s: 纵向串行化(多行合并为一行) │
    │ │ │ -d: 自定义分隔符(默认Tab) │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ tr │ 字符转换│ 一对一替换 -d:删除 -s:压缩重复 │
    │ │ │ -c:补集操作 │
    │ │ │ [:upper:] [:lower:] [:digit:] 等字符类 │
    └──────────┴─────────┴─────────────────────────────────────────┘

    创建测试数据:

    $ printf "ID\\tName\\tAge\\tCity\\n1\\tAlice\\t28\\tBeijing\\n2\\tBob\\t35\\tShanghai\\n3\\tCarol\\t22\\tShenzhen\\n4\\tDavid\\t30\\tHangzhou\\n5\\tEve\\t26\\tChengdu" > people.tsv
    $ cat people.tsv
    IDNameAgeCity
    1Alice28Beijing
    2Bob35Shanghai
    3Carol22Shenzhen
    4David30Hangzhou
    5Eve26Chengdu

    7.2 cut — 列截取

    # 按字段截取(-f 字段号,-d 分隔符默认Tab)
    $ cut -f 2,4 people.tsv
    NameCity
    AliceBeijing
    BobShanghai
    CarolShenzhen
    DavidHangzhou
    EveChengdu

    # 处理 /etc/passwd(以 : 分隔)
    $ cut -d: -f1,7 /etc/passwd | head -5
    root:/bin/bash
    daemon:/usr/sbin/nologin
    bin:/usr/sbin/nologin
    sys:/usr/sbin/nologin
    sync:/bin/sync

    # 按字符位置截取
    $ echo "ABCDEFGHIJ" | cut -c 1-5
    ABCDE

    $ echo "ABCDEFGHIJ" | cut -c 1,3,5,7,9
    ACEGI

    7.3 paste — 行合并

    $ printf "1\\n2\\n3\\n4\\n5" > ids.txt
    $ printf "Alice\\nBob\\nCarol\\nDavid\\nEve" > names.txt

    # 基本:逐行合并(Tab分隔)
    $ paste ids.txt names.txt
    1Alice
    2Bob
    3Carol
    4David
    5Eve

    # 自定义分隔符
    $ paste -d: ids.txt names.txt
    1:Alice
    2:Bob
    3:Carol
    4:David
    5:Eve

    # -s 串行化:多行合并为一行
    $ paste -s -d, ids.txt
    1,2,3,4,5

    7.4 tr — 字符转换

    # 大小写转换
    $ echo "Hello World" | tr "a-z" "A-Z"
    HELLO WORLD

    $ echo "Hello World" | tr "[:upper:]" "[:lower:]"
    hello world

    # 删除字符 (-d)
    $ echo "Hello World 123" | tr -d " "
    HelloWorld123

    # 压缩重复字符 (-s)
    $ echo "Hello World !!!" | tr -s " "
    Hello World !!!

    # 字符集替换
    $ echo "abc123def456" | tr "0-9" "A-J"
    abcBCDdefFGH

    # 补集操作 (-c):保留数字,删除其他
    $ echo "abc123def456" | tr -cd "0-9"
    123456

    7.5 cut / paste / tr 组合实战

    # 日志清洗:Tab→竖线 + 大写→小写
    $ printf "ERROR\\t2026-06-15\\tServer Down!" | tr "\\t" "|" | tr "[:upper:]" "[:lower:]"
    error|2026-06-15|server down!

    # 提取用户名并转大写
    $ cut -d: -f1 /etc/passwd | tr "a-z" "A-Z" | head -5
    ROOT
    DAEMON
    BIN
    SYS
    SYNC

    # 用户名+Shell 并排
    $ paste <(cut -d: -f1 /etc/passwd | head -5) <(cut -d: -f7 /etc/passwd | head -5)
    root/bin/bash
    daemon/usr/sbin/nologin
    bin/usr/sbin/nologin
    sys/usr/sbin/nologin
    sync/bin/sync

    <(command) 进程替换:将命令输出当作临时文件使用,是 bash 高级特性。


    实验八:sort / uniq / join

    8.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ 排序 + 去重 + 连接 │
    ├──────────┬─────────┬─────────────────────────────────────────┤
    │ sort │ 排序 │ 默认按ASCII字典序 │
    │ │ │ -n:数值 -h:人类可读 -M:月份 -r:逆序 │
    │ │ │ -k:按列 -t:分隔符 -u:去重输出 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ uniq │ 去重 │ -c:计数 -d:仅重复行 -u:仅唯一行 │
    │ │ │ ⚠️ 只能处理相邻重复行,通常先sort再uniq │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ join │ 连接 │ 类似SQL JOIN,按公共字段合并两个文件 │
    │ │ │ -a:显示未匹配 -v:仅未匹配 -t:分隔符 │
    └──────────┴─────────┴─────────────────────────────────────────┘

    8.2 sort — 排序

    # 默认按ASCII字典序(大写字母排在小写之前!)
    $ printf "orange\\napple\\nbanana\\nApple\\nOrange" | sort
    apple
    Apple
    banana
    orange
    Orange

    # -r 逆序
    $ printf "orange\\napple\\nbanana\\nApple\\nOrange" | sort -r
    Orange
    orange
    banana
    Apple
    apple

    ASCII 排序规则:大写字母(A-Z: 65-90)的 ASCII 码值 小于 小写字母(a-z: 97-122),所以 Apple 排在 apple 之前。

    # -n 数值排序
    $ printf "10\\n2\\n100\\n5\\n1\\n20" | sort -n
    1
    2
    5
    10
    20
    100

    # -h 人类可读大小排序(识别 K/M/G 单位)
    $ printf "1K\\n10M\\n2G\\n100M\\n1G" | sort -h
    1K
    10M
    100M
    1G
    2G

    # -k 按列排序
    $ printf "Alice 500\\nBob 300\\nCarol 800\\nDavid 200" | sort -k2 -n
    David 200
    Bob 300
    Alice 500
    Carol 800

    # -t 指定分隔符 + -k 按指定列
    $ printf "1:Alice:500\\n2:Bob:300\\n3:Carol:800\\n4:David:200" | sort -t: -k3 -n
    4:David:200
    2:Bob:300
    1:Alice:500
    3:Carol:800

    # -u 去重输出
    $ printf "apple\\nbanana\\napple\\ncherry\\nbanana" | sort -u
    apple
    banana
    cherry

    # -M 月份排序
    $ printf "Mar\\nJan\\nFeb\\nApr\\nDec" | sort -M
    Jan
    Feb
    Mar
    Apr
    Dec

    8.3 uniq — 去重与统计

    # 基本去重(仅合并相邻重复行)
    $ printf "apple\\napple\\nbanana\\nbanana\\nbanana\\ncherry" | uniq
    apple
    banana
    cherry

    # -c 计数(最重要的选项!)
    $ printf "apple\\napple\\nbanana\\nbanana\\nbanana\\ncherry\\napple" | sort | uniq -c | sort -rn
    3 banana
    3 apple
    1 cherry

    # -d 仅显示重复行
    $ printf "apple\\napple\\nbanana\\ncherry\\nbanana" | sort | uniq -d
    apple
    banana

    # -u 仅显示唯一行
    $ printf "apple\\napple\\nbanana\\ncherry\\nbanana" | sort | uniq -u
    cherry

    8.4 sort+uniq 实战:HTTP方法频率统计

    $ printf "GET\\nPOST\\nGET\\nDELETE\\nGET\\nPOST\\nPUT\\nGET" | sort | uniq -c | sort -rn
    4 GET
    2 POST
    1 PUT
    1 DELETE

    这是运维最常用的分析模式:sort | uniq -c | sort -rn — 排序→计数→按频率降序。

    8.5 join — 类SQL连接

    需要两个文件的关键字段已排序。

    $ printf "1 Alice\\n2 Bob\\n3 Carol" > employees.txt
    $ printf "1 Engineer\\n2 Designer\\n3 Manager" > roles.txt

    # 基本连接(默认按第一个字段)
    $ join employees.txt roles.txt
    1 Alice Engineer
    2 Bob Designer
    3 Carol Manager

    # 指定分隔符
    $ printf "1:Alice:50000\\n2:Bob:45000\\n3:Carol:60000" > emp2.txt
    $ printf "1:Engineering\\n2:Design\\n3:Management" > dept.txt
    $ join -t: emp2.txt dept.txt
    1:Alice:50000:Engineering
    2:Bob:45000:Design
    3:Carol:60000:Management

    # 左连接(-a 1:显示file1中未匹配的行)
    $ printf "1 Alice\\n2 Bob\\n3 Carol\\n4 David" > all_emp.txt
    $ printf "1 Engineer\\n3 Manager" > some_roles.txt
    $ join -a 1 all_emp.txt some_roles.txt
    1 Alice Engineer
    2 Bob
    3 Carol Manager
    4 David

    # 仅显示未匹配行(-v 1:file1中有但file2中没有的)
    $ join -v 1 all_emp.txt some_roles.txt
    2 Bob
    4 David


    实验九:comm / diff / patch

    9.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ 文件比较三工具 │
    ├──────────┬─────────┬─────────────────────────────────────────┤
    │ comm │ 逐行比较│ 输出3列:1=仅file1 2=仅file2 3=共有 │
    │ │ │ -1 -2 -3 隐藏对应列 │
    │ │ │ ⚠️ 要求两个文件已排序 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ diff │ 差异 │ 逐行比较,输出差异 │
    │ │ │ -u: unified格式(最常用) │
    │ │ │ -c: context格式 -y: 并排显示 │
    │ │ │ -i: 忽略大小写 -w: 忽略空白 │
    │ │ │ -r: 递归目录比较 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ patch │ 打补丁 │ 将 diff 输出应用到文件 │
    │ │ │ patch < changes.patch 正向应用 │
    │ │ │ patch -R < changes.patch 反向撤销 │
    └──────────┴─────────┴─────────────────────────────────────────┘

    创建测试文件:

    $ printf "apple\\nbanana\\ncherry\\ndate\\nelderberry" > file1.txt
    $ printf "apple\\nbanana\\ncranberry\\ndate\\nfig" > file2.txt

    $ cat file1.txt
    apple
    banana
    cherry
    date
    elderberry

    $ cat file2.txt
    apple
    banana
    cranberry
    date
    fig

    9.2 comm — 逐行比较

    # 三列输出:Tab缩进 = 仅file1 | Tab = 仅file2 | 无缩进 = 共有
    $ comm file1.txt file2.txt
    apple
    banana
    cherry
    cranberry
    date
    elderberry
    fig

    列缩进含义
    第1列 无 仅在 file1 中存在
    第2列 1个Tab 仅在 file2 中存在
    第3列 2个Tab 两个文件共有

    # 隐藏第1列(仅显示file2独有+共有)
    $ comm -1 file1.txt file2.txt
    apple
    banana
    cranberry
    date
    fig

    # 隐藏第3列(仅显示各自独有的行)
    $ comm -3 file1.txt file2.txt
    cherry
    cranberry
    elderberry
    fig

    # -12 仅显示共有行(交集)
    $ comm -12 file1.txt file2.txt
    apple
    banana
    date

    9.3 diff — 差异对比

    # 基本输出(ed风格指令)
    $ diff file1.txt file2.txt
    3c3
    < cherry
    —
    > cranberry
    5c5
    < elderberry
    —
    > fig

    输出解读:3c3 = 第3行 change 为第3行;< = file1(旧),> = file2(新)。

    # unified 格式(-u,最推荐)
    $ diff -u file1.txt file2.txt
    — file1.txt2026-06-15 22:24:42.317639317 +0800
    +++ file2.txt2026-06-15 22:24:42.317639317 +0800
    @@ -1,5 +1,5 @@
    apple
    banana
    -cherry
    +cranberry
    date
    -elderberry
    +fig

    unified 格式解读:— 旧文件,+++ 新文件;@@ -1,5 +1,5 @@ 表示旧文件1-5行→新文件1-5行;- 删除行,+ 新增行。

    # context 格式(-c)
    $ diff -c file1.txt file2.txt
    *** file1.txt2026-06-15 22:24:42.317639317 +0800
    — file2.txt2026-06-15 22:24:42.317639317 +0800
    ***************
    *** 1,5 ****
    apple
    banana
    ! cherry
    date
    ! elderberry
    — 1,5 —-
    apple
    banana
    ! cranberry
    date
    ! fig

    # 并排显示(-y,直观对比)
    $ diff -y file1.txt file2.txt
    appleapple
    bananabanana
    cherry |cranberry
    datedate
    elderberry |fig

    9.4 diff 选项

    # -i 忽略大小写(无输出 = 内容相同)
    $ echo "HELLO" > cap.txt && echo "hello" > lower.txt
    $ diff -i cap.txt lower.txt
    (no output = identical)

    # -w 忽略空白差异
    $ echo "hello world" > with_spaces.txt && echo "hello world" > no_spaces.txt
    $ diff -w with_spaces.txt no_spaces.txt
    (no output = identical)

    # -r 递归比较目录
    $ mkdir -p dir_a dir_b
    $ cp file1.txt dir_a/ && cp file2.txt dir_b/file1.txt
    $ diff -r dir_a dir_b
    diff -r dir_a/file1.txt dir_b/file1.txt
    3c3
    < cherry
    —
    > cranberry
    5c5
    < elderberry
    —
    > fig

    9.5 patch — 补丁的应用与撤销

    # Step 1: 创建补丁
    $ diff -u file1.txt file2.txt > changes.patch
    $ cat changes.patch
    — file1.txt 2026-06-15 22:24:42.317639317 +0800
    +++ file2.txt 2026-06-15 22:24:42.317639317 +0800
    @@ -1,5 +1,5 @@
    apple
    banana
    -cherry
    +cranberry
    date
    -elderberry
    +fig

    # Step 2: 应用补丁
    $ patch file1.txt < changes.patch
    patching file file1.txt

    # Step 3: 验证 — file1 已变成 file2 的内容
    $ cat file1.txt
    apple
    banana
    cranberry
    date
    fig

    # Step 4: 反向应用(撤销补丁)
    $ patch -R file1.txt < changes.patch
    patching file file1.txt

    $ cat file1.txt
    apple
    banana
    cherry
    date
    elderberry

    patch 典型场景:开源项目中用 git format-patch 生成补丁 → 邮件发给维护者 → git am 或 patch 应用。


    实验十:df / du / time

    10.1 知识点概览

    ┌──────────────────────────────────────────────────────────────┐
    │ 磁盘 + 性能测量 │
    ├──────────┬─────────┬─────────────────────────────────────────┤
    │ df │ 文件系统│ -h:人类可读 -i:inode -T:文件系统类型 │
    │ │ 级别 │ 反映整个分区的使用情况 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ du │ 目录/ │ -sh:汇总+人类可读 -a:所有文件 │
    │ │ 文件级 │ –max-depth=N:限制深度 -c:合计 │
    │ │ │ 统计目录/文件实际占用空间 │
    ├──────────┼─────────┼─────────────────────────────────────────┤
    │ time │ 计时 │ real:墙上时钟 user:用户态CPU │
    │ │ │ sys:内核态CPU │
    └──────────┴─────────┴─────────────────────────────────────────┘

    10.2 df — 文件系统磁盘使用

    $ df -h
    Filesystem Size Used Avail Use% Mounted on
    tmpfs 341M 1.1M 340M 1% /run
    /dev/vda1 40G 3.6G 35G 10% /
    tmpfs 1.7G 0 1.7G 0% /dev/shm
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 341M 12K 341M 1% /run/user/0

    本机信息:根分区 /dev/vda1 40G(ext4),已用 3.6G(10%),tmpfs 是内存文件系统。

    # -i 查看 inode 使用情况
    $ df -i
    Filesystem Inodes IUsed IFree IUse% Mounted on
    tmpfs 436466 692 435774 1% /run
    /dev/vda1 2621440 109166 2512274 5% /
    tmpfs 436466 1 436465 1% /dev/shm
    tmpfs 436466 3 436463 1% /run/lock
    tmpfs 87293 33 87260 1% /run/user/0

    # -T 显示文件系统类型
    $ df -T
    Filesystem Type 1K-blocks Used Available Use% Mounted on
    tmpfs tmpfs 349176 1044 348132 1% /run
    /dev/vda1 ext4 41169244 3696420 35673984 10% /
    tmpfs tmpfs 1745864 0 1745864 0% /dev/shm
    tmpfs tmpfs 5120 0 5120 0% /run/lock
    tmpfs tmpfs 349172 12 349160 1% /run/user/0

    10.3 du — 目录/文件大小

    # 汇总各目录大小
    $ du -sh /tmp/cmd-lab-01 /tmp/cmd-lab-02 /tmp/cmd-lab-03
    16K/tmp/cmd-lab-01
    68K/tmp/cmd-lab-02
    8.0K/tmp/cmd-lab-03

    # 限制深度查看(类似 tree)
    $ du -h –max-depth=1 /tmp/cmd-lab-05
    44K/tmp/cmd-lab-05/src
    20K/tmp/cmd-lab-05/logs
    68K/tmp/cmd-lab-05

    # -a 列出所有文件
    $ du -a /tmp/cmd-lab-05 | head -10
    0/tmp/cmd-lab-05/README.md
    0/tmp/cmd-lab-05/src/test/java/com/example/AppTest.java
    4/tmp/cmd-lab-05/src/test/java/com/example
    8/tmp/cmd-lab-05/src/test/java/com
    12/tmp/cmd-lab-05/src/test/java
    16/tmp/cmd-lab-05/src/test
    4/tmp/cmd-lab-05/src/main/resources/application.yml
    8/tmp/cmd-lab-05/src/main/resources
    0/tmp/cmd-lab-05/src/main/java/com/example/App.java
    0/tmp/cmd-lab-05/src/main/java/com/example/Utils.java

    # -c 显示合计
    $ du -shc /tmp/cmd-lab-01 /tmp/cmd-lab-02 /tmp/cmd-lab-03
    16K/tmp/cmd-lab-01
    68K/tmp/cmd-lab-02
    8.0K/tmp/cmd-lab-03
    92Ktotal

    # 按大小排序各测试目录
    $ du -sh /tmp/cmd-lab-*/ 2>/dev/null | sort -rh
    68K/tmp/cmd-lab-05/
    68K/tmp/cmd-lab-02/
    28K/tmp/cmd-lab-08/
    16K/tmp/cmd-lab-01/
    12K/tmp/cmd-lab-09/
    8.0K/tmp/cmd-lab-03/
    4.0K/tmp/cmd-lab-10/
    4.0K/tmp/cmd-lab-04/

    10.4 df vs du 对比

    维度dfdu
    视角 文件系统级别 目录/文件级别
    数据来源 超级块(superblock) 递归遍历 inode
    是否包含已删除但被进程占用的文件 包含(deleted但fd未释放) 不包含
    典型用法 监控磁盘整体健康 排查哪个目录占用大
    常见差异 df 显示磁盘满了 du 显示还有很多空间

    经典踩坑:日志文件被 rm 删除但进程持有句柄未释放 → df 显示满 du 显示空 → lsof | grep deleted 排查。

    10.5 time — 命令计时

    $ time ls -laR /etc > /dev/null
    real0m0.009s
    user0m0.001s
    sys0m0.007s

    $ time sleep 0.5
    real0m0.501s
    user0m0.001s
    sys0m0.000s

    $ time find /tmp/cmd-lab-05 -name "*.java" > /dev/null
    real0m0.001s
    user0m0.000s
    sys0m0.001s

    时间类型含义sleep 示例解读
    real 墙上时钟(实际流逝时间) 0.501s ≈ 0.5s等待+启动开销
    user 用户态 CPU 时间 0.001s(sleep 不需要CPU运算)
    sys 内核态 CPU 时间 0.000s(几乎无系统调用)

    10.6 文件系统类型对照

    类型特点适用场景
    ext4 Linux 默认,成熟稳定 通用(本机使用)
    xfs 高性能,支持大文件 数据库/大数据
    btrfs COW、快照、压缩 现代容器/桌面
    tmpfs 内存文件系统 临时文件//tmp//dev/shm
    overlay 联合文件系统 Docker 容器镜像

    10.7 dd 创建大文件演示

    $ dd if=/dev/zero of=testfile bs=1M count=10 2>&1
    10+0 records in
    10+0 records out
    10485760 bytes (10 MB, 10 MiB) copied, 0.00248765 s, 4.2 GB/s

    $ ls -lh testfile
    -rw-r–r– 1 root root 10M Jun 15 22:24 testfile

    $ du -h testfile
    10Mtestfile

    dd 参数:if=输入文件,of=输出文件,bs=块大小,count=块数量。/dev/zero 提供无限零字节流。


    命令速查表

    文件目录操作

    命令核心选项一行示例
    ls -la -lh -ltr -R ls -ltr –color=auto
    cd – .. ~ / cd – 回到上次目录
    pwd -P -L pwd -P 显示物理路径
    mkdir -p -m -v mkdir -p a/b/c
    rm -rf -i -v rm -rfv old_dir/
    mv -i -v mv old new
    cp -rp -u -a cp -rp src/ dst/
    cat -n -b -s cat -n file.txt
    nl -b a/t -n ln/rn nl -b a file.txt

    文本浏览

    命令核心选项一行示例
    head -n N -c N head -n 20 file.txt
    tail -n N -f -n +N tail -f /var/log/syslog
    more 分页浏览 more longfile.txt
    less 前后翻页/搜索 less -N longfile.txt

    搜索定位

    命令核心选项一行示例
    which -a which python3
    whereis -b -m -s whereis -b ls
    locate -i -r locate passwd
    find -name -type -size -mtime -exec find . -name '*.log' -mtime +7 -delete
    grep -i -v -n -r -E -A/B/C grep -rn 'TODO' src/

    文本处理

    命令核心选项一行示例
    wc -l -c -w -L wc -l *.txt
    cut -f -d -c cut -d: -f1,7 /etc/passwd
    paste -s -d paste -d: file1 file2
    tr -d -s -c tr 'a-z' 'A-Z' < file
    sort -n -r -k -t -h sort -t: -k3 -n file
    uniq -c -d -u sort | uniq -c | sort -rn
    join -t -a -v join -t: file1 file2
    comm -1 -2 -3 -12 comm -12 file1 file2
    diff -u -c -y -r diff -u old.txt new.txt
    patch < patch -R patch < fix.patch
    xargs -n -I -0 find . -name '*.tmp' | xargs rm

    系统信息

    命令核心选项一行示例
    df -h -i -T df -h /
    du -sh -a –max-depth -c du -sh * | sort -rh
    time bash内建 time ls -R /usr/ > /dev/null
    dd if= of= bs= count= dd if=/dev/zero of=test bs=1M count=10

    本文档所有命令输出均来自华为云 ECS ecs-b97e-0001 (Ubuntu 24.04 LTS, Linux 6.8.0),于 2026-06-15 真实执行。

    赞(0)
    未经允许不得转载:171主机测评 » Linux 操作命令完全指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址