Linux 命令使用案例:文档编辑和文本处理

1️⃣cat命令 – 在终端设备上显示文件内容

一、核心参数详解与使用场景

参数全称/含义使用场景示例
-n--number (行号)显示所有行的行号。用于查看代码、配置文件或日志时快速定位特定行。cat -n server.conf
-b--number-nonblank (非空行号)只对非空行编号。在查看代码时比 -n 更清爽,忽略空行。cat -b script.py
-s--squeeze-blank (压缩空行)将连续的多行空行压缩成一行。使输出更紧凑,便于阅读。cat -s logfile.txt
-A--show-all (显示所有)相当于 -vET,显示所有不可见的字符(如制表符、行尾符、换页符)。cat -A file_with_hidden_chars
-T(显示制表符)将制表符 (Tab) 显示为 ^I。用于检查代码缩进是空格还是Tab。cat -T script.py
-E--show-ends (显示行尾)在每行末尾显示 $ 符号。用于确认行是否结束,或查看是否有尾随空格。cat -E file.txt
-v--show-nonprinting (显示不可打印字符)使用 ^M- 符号显示不可打印字符(除了换行符和制表符)。cat -v binary_data.txt

二、常用组合与实战场景

1. 查看与阅读文件(最基础用法)
# 查看一个文件的内容
cat filename.txt

# 查看多个文件的内容(按顺序连接显示)
cat file1.txt file2.txt

# 显示带行号的文件内容(阅读代码/日志神器)
cat -n application.log

# 显示带行号且忽略空行的文件内容(更清晰)
cat -b server.conf
2. 创建新文件或追加内容(无需文本编辑器)
# 1. 创建新文件并输入内容(输入完成后按 Ctrl+D 结束)
cat > new_file.txt
This is the first line.
This is the second line.
# [Ctrl+D]

# 2. 向已存在文件末尾追加内容
cat >> existing_file.txt
This line is appended to the end.
# [Ctrl+D]

场景:快速创建简单的配置文件、脚本或笔记,或者在脚本中动态生成文件。

3. 文件合并与重定向(核心功能)
# 将 file1 和 file2 合并成一个新文件 merged_file
cat file1.txt file2.txt > merged_file.txt

# 将 file3 的内容追加到 merged_file 的末尾
cat file3.txt >> merged_file.txt

# 将一个文件的内容覆盖到另一个文件(清空目标文件后写入)
cat source.txt > destination.txt

场景:合并多个日志文件、拆分后的大文件重组、备份配置等。

4. 诊断文件格式问题(高级技巧)
# 检查文件中是否包含Windows换行符(^M)或混合缩进
cat -A script.py
# 可能输出:This line has a Windows carriage return^M$

# 检查缩进是Tab还是空格(Tab会显示为 ^I)
cat -T index.html
# 输出:<div>^I<p>Hello</p>^I</div>

# 检查行尾是否有空格(空格会在 $ 前面显示)
cat -E document.txt
# 输出:This line has trailing spaces      $

场景:在跨平台开发(Windows/Linux)时诊断编码和格式问题,保证脚本和配置文件的兼容性。

5. 管道组合(与其他命令协作)

cat 常被视为不必要的管道使用(Useless Use of Cat),因为许多命令可以直接读文件。但在某些场景下,从标准输入读取更灵活。

# 1. 将文件内容通过管道传递给处理命令(经典用法)
cat large_file.txt | grep "error"        # 在文件中搜索关键词
cat access.log | sort | uniq -c          # 排序并统计出现次数

# 2. 将文件内容作为另一个命令的输入
cat list_of_urls.txt | wget -i -         # 下载文件中列出的所有URL

# 3. 与 here-document 结合,向交互式命令输入多行内容
cat <<EOF | mysql -u root -p
CREATE DATABASE mydb;
USE mydb;
EOF

三、注意事项与常见误区

  1. 不要用 cat 查看大型文件

    • 问题cat 会一次性输出整个文件内容到终端,如果文件巨大(如几个GB的日志),会导致终端卡死或刷屏。
    • 解决方案:使用分页工具 less(推荐)或 more
      less huge_file.log    # 可上下翻页、搜索、退出后不留屏幕垃圾
      more huge_file.log    # 基础分页
      
  2. 避免“无用的cat”(Cat Abuse)

    • 不推荐cat file | grep "pattern" (多了一个不必要的进程)
    • 推荐grep "pattern" file (更高效,直接由grep读取文件)
    • 例外:当需要多个源的数据时,cat 管道很有用:
      cat file1 file2 | grep "pattern" # 从两个文件中搜索
      
  3. 谨慎处理二进制文件

    • cat 可以输出二进制文件(如图片、压缩包),但输出到终端会导致乱码,甚至终端会话崩溃。
    • 用途:通常用于二进制文件的合并或重定向,而不是查看。
      cat picture_part1 picture_part2 > complete_picture.jpg
      

四、常用组合速查表

场景命令组合说明
查看代码/配置cat -n filename带行号查看
检查格式cat -A filename显示所有隐藏字符
检查缩进cat -T filename显示Tab为^I
合并文件cat file1 file2 > merged合并为新文件
追加内容cat >> file + 输入追加到文件末尾
快速创建cat > file + 输入创建新文件
管道输入cat file | command将文件内容传给其他命令

2️⃣grep命令 – 强大的文本搜索工具

一、核心参数详解与使用场景

1. 匹配控制参数(决定搜索什么)
参数全称/含义使用场景示例
-i--ignore-case (忽略大小写)大小写不敏感搜索。用于搜索不确定大小写的单词(如 “error”, “Error”, “ERROR”)。grep -i "error" logfile.txt
-v--invert-match (反向匹配)只显示不包含匹配模式的行。用于排除噪音,查找异常。grep -v "DEBUG" app.log (排除DEBUG行)
-w--word-regexp (单词匹配)只匹配完整的单词,而不是单词的一部分。防止误匹配(如从 background 中匹配 back)。grep -w "root" /etc/passwd
-x--line-regexp (行匹配)只匹配整行完全符合模式的行。常用于精确匹配配置文件中的设置。grep -x "PORT=8080" config.env
-e PATTERN--regexp=PATTERN (模式)明确指定一个搜索模式。主要用于搜索以 - 开头的模式,或指定多个模式。grep -e "-v" -e "-i" script.sh
-f FILE--file=FILE (文件)从文件中读取要搜索的模式(每行一个模式)。用于搜索一大组预定义的字符串。grep -f search_terms.txt big_file.txt
-P--perl-regexp (Perl正则)使用功能强大的 Perl 兼容正则表达式 (PCRE)。支持 \d, \s, 非贪婪匹配 .*? 等高级特性。grep -P "\d{3}-\d{4}" contacts.txt (匹配电话号码)
2. 输出控制参数(决定如何显示结果)
参数全称/含义使用场景示例
-n--line-number (行号)显示匹配行所在文件中的行号。用于快速定位,尤其是在代码或日志文件中。grep -n "Exception" error.log
-c--count (计数)只显示匹配行的数量,而不是行本身。用于统计出现次数。grep -c "GET" access.log (统计GET请求次数)
-o--only-matching (只输出匹配部分)只输出匹配到的文本部分,而不是整行。用于提取特定格式的字符串。grep -oP 'src="\K[^"]+' page.html (提取图片URL)
-q--quiet / --silent (静默)静默模式。不输出任何结果,只根据是否找到匹配行设置退出状态码 ($?)。主要用于脚本中的条件判断。if grep -q "FATAL" log; then echo "Found error"; fi
-a--text (文本)将二进制文件视为文本文件来处理。用于在二进制文件中搜索文本字符串。grep -a "text" binary_file
-H / -h--with-filename / --no-filename (显示/隐藏文件名)-H:强制显示文件名(默认在多文件搜索时显示)。-h:强制隐藏文件名。grep -H "pattern" file1 file2
--color=auto(颜色)对匹配到的文本进行高亮显示。极大地提高可读性。推荐在 ~/.bashrc 中设置别名 alias grep='grep --color=auto'grep --color=auto "TODO" *.py
3. 上下文控制参数(显示匹配行周围的内容)
参数全称/含义使用场景示例
-C NUM--context=NUM (上下文)显示匹配行及其前后各 NUM 行。提供上下文,便于理解。grep -C 2 "crash" logfile (显示崩溃前后2行)
-B NUM--before-context=NUM (前上下文)只显示匹配行及其前面 NUM 行grep -B 3 "Error:" logfile (查看错误发生前的日志)
-A NUM--after-context=NUM (后上下文)只显示匹配行及其后面 NUM 行grep -A 5 "Starting process" logfile (查看启动后的输出)
4. 文件选择参数(决定在哪里搜索)
参数全称/含义使用场景示例
-r--recursive (递归)递归搜索指定目录下的所有文件。用于在项目目录或日志目录中全局搜索。grep -r "function_name" /src/
-R(同上,但遵循符号链接)-r,但会递归到符号链接指向的目录。grep -R "deprecated" /usr/include/
--include=GLOB(包含文件)在递归搜索时,只搜索文件名匹配 GLOB 模式的文件。用于限制文件类型。grep -r --include="*.js" "console.log" .
--exclude=GLOB(排除文件)在递归搜索时,排除文件名匹配 GLOB 模式的文件。用于忽略特定文件。grep -r --exclude="*.min.js" "function" . (排除压缩的JS文件)
--exclude-dir=DIR(排除目录)在递归搜索时,排除名为 DIR 的目录。用于跳过 .git, node_modules 等目录。grep -r --exclude-dir=.git "pattern" .

二、常用组合与实战场景

1. 日志分析(最经典场景)
# 查找所有ERROR日志,并显示行号和高亮
grep -n --color=auto "ERROR" application.log

# 查看ERROR日志及其后10行上下文(查看错误堆栈)
grep -A 10 "ERROR" application.log

# 统计不同HTTP状态码的出现次数
grep -oP 'HTTP/1.\d" \K\d{3}' access.log | sort | uniq -c

# 查找过去一小时内产生的日志(结合find)
find /var/log -name "*.log" -mmin -60 -exec grep -l "Fatal" {} \;
2. 代码开发
# 在项目中递归搜索所有使用某个函数的文件(排除二进制文件)
grep -rn --include="*.py" "def calculate" /myproject/

# 搜索TODO或FIXME注释
grep -rn --color=auto "TODO\|FIXME" src/

# 查找所有包含特定头文件的C文件
grep -l "#include <openssl/sha.h>" *.c

# 精确查找一个变量名,避免找到函数名或注释(-w单词匹配)
grep -wn "count" *.c
3. 系统管理与审计
# 检查密码为空的账户(反向匹配)
grep -v ':\*:\|:\!:' /etc/shadow | grep -v ':\$'

# 查找所有可执行文件(SUID/SGID)
find / -type f -perm /6000 2>/dev/null | grep -v "/proc/"

# 检查网络连接状态(ESTABLISHED)
netstat -tulnap | grep -E "(ESTABLISHED)"
4. 数据提取与处理
# 从HTML中提取所有URL
grep -oP '(?<=href=")[^"]*' webpage.html

# 提取所有IPv4地址
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" file.txt

# 提取所有邮箱地址
grep -oE "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" contacts.txt
5. 高级递归搜索组合
# 在Java文件中搜索,但排除test目录和所有jar包
grep -r --include="*.java" --exclude-dir=test --exclude="*.jar" "ArrayList" .

# 在多个目录中搜索多个模式,显示文件名和行号
grep -rn -e "pattern1" -e "pattern2" /path1/ /path2/

三、性能优化与注意事项

  1. 固定字符串搜索 (-F)

    • 如果你的模式是简单的字符串,没有正则元字符(如 ., *, []),使用 -F (或 fgrep) 会更快,因为它会禁用正则引擎。
  2. 减少搜索范围

    • 使用 --include--exclude 系列参数可以大幅提升递归搜索的速度,避免搜索无关文件(如 *.min.js, *.zip, .git/)。
  3. 避免在根目录 / 下递归

    • grep -r pattern / 会搜索整个硬盘,包括虚拟文件系统(如 /proc, /sys),导致性能极差和大量错误。总是使用 2>/dev/null 或指定具体路径。
  4. 理解正则表达式

    • grep 的威力在于正则。学习基础正则(BRE)和扩展正则(ERE -E 或 PCRE -P)能极大提升你的搜索能力。
    • 常用元字符:., *, +, ?, [], [^], ^, $, |, (), \d, \s, \K (零宽断言)。

总结:高频组合速查表

场景推荐命令组合说明
基础搜索grep -n --color=auto "pattern" file带行号和高亮
忽略大小写grep -i "pattern" file大小写不敏感
统计次数grep -c "pattern" file只显示匹配行数
递归搜索代码grep -rn --include="*.ext" "pattern" dir/在指定类型文件中搜索
查看上下文grep -C 3 "pattern" file查看匹配行前后3行
提取数据grep -oP "regex_pattern" file只输出匹配到的部分
脚本判断if grep -q "pattern" file; then ...静默模式用于条件判断
排除噪音grep -v "unwanted_pattern" file反向匹配,排除不需要的行

4️⃣tail命令 – 查看文件尾部内容

tail 命令是 Linux 系统管理和日志查看中使用频率最高的命令之一。它的核心功能是显示文件的末尾部分内容,尤其擅长实时监控不断增长的文件(如日志文件)。

以下是 tail 命令的参数详解、使用场景和经典组合。


一、核心参数详解与使用场景

参数全称/含义使用场景示例
-n NUM / -NUM--lines=NUM (行数)显示文件最后的 NUM 行。这是最常用的参数。省略 -n,直接使用 -数字 是常见简写。tail -n 50 file.log
tail -50 file.log (显示最后50行)
-f--follow (跟随)实时监视文件尾部内容,并在新内容追加到文件时持续输出日志监控神器tail -f /var/log/syslog
-F(跟随 by-name)类似 -f,但更强大。它会跟踪文件名而非文件描述符。即使文件被轮转/切割/删除重建,它也能继续跟踪。监控日志的首选参数tail -F /var/log/nginx/access.log
-c NUM--bytes=NUM (字节数)显示文件最后的 NUM 个字节。用于查看固定大小的尾部内容,尤其是二进制文件。tail -c 1024 data.bin (显示最后1KB)
-q--quiet / --silent (静默)当查看多个文件时,不显示每个文件的文件名标题。用于合并查看多个文件的尾部。tail -q -n 5 file1.log file2.log
-v--verbose (详细)当查看多个文件时,总是显示每个文件的文件名标题tail -v -n 5 *.log
--pid=PID(进程ID)-f 联用,当指定进程 PID 终止后,自动退出 tail 命令。用于监控由特定进程生成的日志。tail -f --pid=$(pgrep myapp) myapp.log
-s SEC--sleep-interval=SEC (间隔)-f 联用,设置检查文件更新的时间间隔(默认为1.0秒)。降低监控频率以减少系统负载。tail -f -s 5 file.log (每5秒检查一次)

二、常用组合与实战场景

1. 日志查看与监控(最核心场景)
# 1. 快速查看日志的最后10行(默认行为)
tail /var/log/syslog

# 2. 查看日志的最后100行
tail -n 100 /var/log/nginx/access.log

# 3. 实时监控日志文件(最常用组合)
tail -f /var/log/auth.log
# 按 Ctrl+C 终止监控

# 4. 实时监控并显示行号(方便定位)
tail -f -n 50 /var/log/app.log | nl

# 5. 强力实时监控(应对日志轮转 - log rotation)
# 如果使用 `-f`,当日志从 access.log 轮转为 access.log.1 时,跟踪会停止。
# 使用 `-F` 可以持续跟踪新生成的 access.log 文件。
tail -F /var/log/nginx/access.log

场景:实时调试应用程序、监控系统安全(登录尝试)、分析Web流量。

2. 组合过滤与实时分析(超级实用)

tail 的强大之处在于能与 grep, awk, cut 等命令组合,形成强大的实时分析管道。

# 1. 实时监控并只显示包含 "ERROR" 的行
tail -f app.log | grep --line-buffered "ERROR"
# `--line-buffered` 确保 grep 结果实时输出,而非缓存后输出

# 2. 实时监控并高亮关键词
tail -f app.log | grep --color=auto -E "ERROR|WARN|INFO"

# 3. 实时监控并提取特定字段(例如,从JSON日志中提取状态码)
tail -f api.log | grep -oP '"status":\s*\K\d+'

# 4. 实时监控并统计(例如,统计5秒内的500错误数)
tail -f -s 5 access.log | grep -c " 500 "
# 注意:这每5秒输出一个数字,表示过去5秒内500错误的次数
3. 对比与检查文件
# 1. 静默查看多个文件的最后几行(不显示文件名)
tail -q -n 3 file1.txt file2.txt

# 2. 详细查看多个文件的最后几行(显示文件名)
tail -v -n 3 *.config

# 3. 查看文件的最后1K内容(常用于检查文件是否完整结尾)
tail -c 1024 large_file.bin > last_kb.bin
4. 高级用法与脚本结合
# 1. 监控日志,并在出现特定关键词时触发操作(邮件/脚本)
tail -f /var/log/daemon.log | while read line; do
  if echo "$line" | grep -q "Fatal Error"; then
    echo "$line" | mail -s "ALERT on $(hostname)" admin@example.com
  fi
done

# 2. 监控一个由特定进程创建的日志文件,进程退出则停止监控
APP_PID=$(pgrep -f "my_application")
tail -f --pid=$APP_PID /tmp/my_application.log

# 3. 从指定行开始显示(使用 `sed` 或 `awk` 辅助)
# 显示从第1000行到文件末尾的内容(相当于 `tail -n +1000`)
sed -n '1000,$p' huge_file.log

三、tail -ftail -F 的区别(重要!)

这是 tail 命令最关键的一个知识点。

  • tail -f (follow descriptor):

    • 跟踪的是文件的描述符 (inode)。
    • 优点:即使文件被重命名(如 mv logfile.log logfile.log.old)或删除,只要仍有进程持有该文件的描述符(如仍在运行的Web服务器),-f 就能继续读取内容。
    • 缺点:当日志轮转发生时(如 logrotateaccess.log 重命名为 access.log.1 并新建一个 access.log),-f 会继续跟踪旧的 access.log.1(因为inode没变),而不会跟踪新的 access.log
  • tail -F (follow name):

    • 跟踪的是文件的名字
    • 行为:它会定期检查文件是否被删除或重建。如果文件名字被重新创建(如日志轮转后新建了一个同名日志文件),它会自动重新打开新文件并继续跟踪。
    • 场景几乎总是你应该用于监控日志的参数,因为它能优雅地处理日志轮转。

结论:在监控可能被轮转的日志时,始终使用 tail -F


四、常用组合速查表

场景命令组合说明
查看日志结尾tail -n 100 file.log查看最后100行
实时监控日志tail -f file.log基本实时监控
实时监控(支持轮转)tail -F file.log生产环境推荐
监控并过滤tail -F app.log | grep "ERROR"只看错误信息
监控并高亮tail -F app.log | grep --color "WARN"高亮警告信息
查看多个文件tail -v -n 5 *.log查看每个日志最后5行并显示文件名
轻量级监控tail -f -s 2 file.log每2秒检查一次更新,降低负载

总结与最佳实践

  1. 默认习惯:查看日志时,养成先看最后几行 (tail -n 50) 的习惯,快速了解最新状态。
  2. 监控首选:需要实时监控时,总是使用 tail -F 而不是 tail -f,以应对日志轮转。
  3. 组合利器:将 tail -Fgrep, awk, cut 等命令通过管道结合,是系统调试和日志分析的王牌技巧
  4. 谨慎操作tail 是只读命令,相对安全。但在脚本中使用管道组合时,确保后面的命令不会意外阻塞或产生非预期操作。

5️⃣sed命令 – 批量编辑文本文件

sed (Stream Editor) 是 Linux 中最强大、最常用的文本处理工具之一。它以其非交互式基于正则表达式的特性而闻名,特别适合在脚本中执行批量文本替换、删除、提取等操作。

理解 sed 的核心在于理解它的 [地址]命令 语法。地址 用于指定要操作的行,命令 指定要执行的操作。


一、核心参数详解与使用场景

1. 执行方式参数
参数全称/含义使用场景示例
-e script--expression=script (表达式)添加要执行的 sed 脚本命令。用于在命令行中执行多个操作。sed -e 's/foo/bar/' -e '/baz/d' file.txt
-f script-file--file=script-file (文件)从文件中读取 sed 脚本命令。当命令非常复杂或需要重复使用时。sed -f commands.sed file.txt
-i[SUFFIX]--in-place[=SUFFIX] (原地编辑)直接修改源文件。这是最危险的参数,也是最常用的之一。SUFFIX 用于在修改前创建备份sed -i.bak 's/old/new/g' file.txt (创建备份后修改) sed -i '' 's/old/new/g' file (macOS 下无备份修改)
-n--quiet / --silent (静默)禁止自动打印模式空间。通常与 p 命令结合,只打印被处理过的行。sed -n '10p' file (只打印第10行)
2. 常用 sed 命令 (在 -e 或脚本中使用)
命令功能使用场景示例
s/regexp/replacement/flags替换 (Substitute)最常用的命令。将匹配 regexp 的文本替换为 replacementsed 's/foo/bar/g' file.txt
d删除 (Delete)删除匹配的行。sed '/pattern/d' file.txt
p打印 (Print)打印当前模式空间。通常与 -n 参数一起使用。sed -n '/pattern/p' file.txt
a\text追加 (Append)在指定行后面追加一行 textsed '3a\This is new line' file.txt
i\text插入 (Insert)在指定行前面插入一行 textsed '1i\This is the first line' file.txt
c\text更改 (Change)text 替换匹配的行。sed '/old_line/c\This is the new line' file.txt
y/src/dst/转换 (Transform)类似 tr 命令,将 src 中的字符逐个转换为 dst 中的字符。sed 'y/abc/ABC/' file.txt (a->A, b->B, c->C)
q退出 (Quit)在处理完指定行后立即退出 sed,不再处理后续行。用于提取文件开头部分。sed '10q' file.txt (打印前10行,类似 head)
3. 地址定址 (决定对哪些行进行操作)
地址格式含义示例
n数字,指定第 n 行sed '5d' file (删除第5行)
$最后一行sed '$d' file (删除最后一行)
/regexp/匹配正则表达式的行sed '/^#/d' file (删除所有注释行)
n,m从第 n 行到第 m 行sed '10,20d' file (删除10到20行)
n,+m从第 n 行到第 n+m 行sed '10,+5d' file (删除10到15行)
n~m从第 n 行开始,每隔 m 行操作一次sed '1~2d' file (删除所有奇数行)
$!除了最后一行之外的所有行sed '$!d' file (只保留最后一行)
4. 替换命令 (s///) 的标志 (flags)
标志功能示例
g全局替换。替换行内所有匹配项,而不仅仅是第一个。sed 's/ /,/g' file (将所有空格替换为逗号)
p打印。如果替换成功,则打印该行。常与 -n 联用。sed -n 's/pattern/replacement/p' file
w file写入。将替换成功的行写入到指定文件。sed 's/pattern/replacement/w newfile.txt' file
iI忽略大小写 (GNU sed 扩展)。sed 's/foo/bar/i' file (匹配 FOO, Foo, foO 等)
数字替换第 N 个匹配项。sed 's/ /,/2' file (只替换每行的第二个空格)

二、常用组合与实战场景

1. 文本替换 (最核心功能)
# 1. 将文件中所有 "apple" 替换为 "orange" (只输出到屏幕,不修改文件)
sed 's/apple/orange/g' file.txt

# 2. 直接修改源文件 (极其危险,务必先测试无 -i 的命令)
sed -i.bak 's/old_string/new_string/g' important_file.cfg
# 先备份 original_file.cfg.bak, 然后修改 original_file.cfg

# 3. 替换每行第2次出现的 "cat" 为 "dog"
sed 's/cat/dog/2' file.txt

# 4. 使用不同的分隔符 (当模式或替换内容包含 `/` 时非常有用)
sed 's|/usr/local|/opt|g' path.conf # 使用 | 作为分隔符
sed 's#/old/path#/new/path#g' file  # 使用 # 作为分隔符

# 5. 使用分组反向引用 (提取和重用部分模式)
echo "Hello World" | sed 's/\(Hello\) \(World\)/\2 \1/'
# 输出: World Hello (交换了两个单词的位置)
# 现代 sed 支持 -E 选项使用扩展正则,避免转义括号
sed -E 's/(Hello) (World)/\2 \1/'
2. 行内容编辑 (删除、插入、追加)
# 1. 删除所有空行
sed '/^$/d' file.txt

# 2. 删除所有注释行 (以 # 开头的行)
sed '/^#/d' config.conf

# 3. 删除包含 "debug" 的行
sed '/debug/d' script.sh

# 4. 在第3行后追加一行文本
sed '3a\This line is added after line 3' file.txt

# 5. 在文件开头插入一行
sed '1i\This is the new first line' file.txt

# 6. 在匹配到 "SERVERNAME" 的行后追加配置
sed '/SERVERNAME/a\127.0.0.1 example.com' /etc/hosts
3. 文本提取与过滤 (类似 grep)
# 1. 打印包含 "error" 的行 (类似 grep)
sed -n '/error/p' system.log

# 2. 打印第10到第20行 (类似 sed -n '10,20p' 或 head -20 | tail -11)
sed -n '10,20p' large_file.txt

# 3. 打印从匹配 "START" 的行到匹配 "END" 的行之间的内容
sed -n '/START/,/END/p' data.txt

# 4. 只打印匹配行的上一行 (使用保持空间的高级技巧)
sed -n '/pattern/{x;p;d}; x' file.txt
4. 文件原地修改与备份 (脚本中的经典用法)
# 1. 安全修改:先备份原文件(.bak),再修改
sed -i.bak 's/old/new/g' file1.txt file2.txt

# 2. 为所有 .txt 文件的行尾添加分号
for f in *.txt; do
    sed -i 's/$/;/' "$f"
done

# 3. 移除Windows文件中的回车符 (^M)
sed -i 's/\r$//' script.sh # 从 Windows 拷贝到 Linux 后的必要操作
5. 高级技巧与复杂脚本
# 1. 多重操作:先删除空行,再替换文本,最后删除注释行
sed -e '/^$/d' -e 's/foo/bar/g' -e '/^#/d' file.txt

# 2. 使用标签进行条件分支(很少用,但功能强大)
sed '{:start /pattern/{s/foo/bar/; p; d;}; /anotherpattern/b start}' file.txt

# 3. 将多个sed命令写入文件,然后执行
# commands.sed 内容:
# /^#/d    # 删除注释行
# s/old/new/g # 全局替换
sed -f commands.sed input.txt

三、注意事项与最佳实践

  1. -i 参数是危险的:它会直接修改源文件。永远先在不带 -i 的情况下测试你的 sed 命令,确认输出无误后再使用 -i。使用 -i.bak 创建备份是一个好习惯。

  2. 正则表达式贪婪性sed 默认使用贪婪匹配。例如 s/.*:// 会删除直到最后一个冒号的所有内容,而不是第一个。

  3. 平台差异

    • GNU sed (Linux) 功能最丰富,支持 \t, \n 等转义和 -i 不带参数。
    • BSD sed (macOS) 要求 -i '' 才能进行无备份的原位编辑,且某些扩展(如 \t)可能不被支持。在 macOS 上,建议使用 gsed (GNU sed)。
  4. 性能考量:对于处理非常大的文件,sed 非常高效,因为它是流式编辑器,不会一次性将整个文件加载到内存中。

  5. awk 的选择

    • 对于简单的行内替换和删除sed 更简洁。
    • 对于基于列的文本处理、计算和更复杂的逻辑awk 通常是更好的选择。

总结:高频组合速查表

场景命令组合说明
简单替换sed 's/old/new/g' file全局替换
直接修改文件sed -i.bak 's/old/new/g' file备份后修改
删除空行sed '/^$/d' file删除所有空行
删除注释行sed '/^#/d' file删除以 # 开头的行
提取特定行sed -n '10p' file只打印第10行
提取范围行sed -n '10,20p' file打印10到20行
文件末尾追加sed '$a\new line' file在最后一行后追加
移除Windows回车sed -i 's/\r$//' winfile.txt转换DOS格式为UNIX格式

6️⃣vi命令 – 文本编辑器

vi(及其增强版 vim)是 Linux 和 Unix 系统中最经典、最强大的文本编辑器。它以其高效率(完全键盘操作)和无处不在(预装在几乎所有类 Unix 系统中)而著称。

学习 vi 的关键在于理解其模式概念和将命令组合起来的哲学。以下是其核心参数、模式、命令和组合的详细解析。


一、启动参数与使用场景

这些参数主要在命令行中启动 vi / vim 时使用。

参数全称/含义使用场景示例
+[n](直接跳转)启动后直接将光标定位到第 n 行。用于快速修复特定行的错误。vi +10 script.py (打开并跳至第10行)
+/pattern(直接搜索)启动后直接搜索并定位到第一个匹配 pattern 的地方。用于快速找到特定内容。vi +/function app.js (打开并搜索"function")
-R(只读模式)以只读模式打开文件。防止意外修改重要文件。等同于 view 命令。vi -R /etc/fstab
-r(恢复模式)恢复因意外退出来保存的交换文件。用于文件恢复。vi -r myfile.txt (列出可恢复的交换文件) vi -r
-c 'command'(执行命令)启动后立即执行指定的 ex 模式命令。用于自动化初始操作。vi -c 'set number' -c 'syntax on' file.c (打开显示行号和语法高亮)
-o[N](水平分割)水平分割窗口打开多个文件N 指定窗口数。vi -o2 file1.txt file2.txt (水平打开两个文件)
-O[N](垂直分割)垂直分割窗口打开多个文件N 指定窗口数。vi -O3 app.js style.css index.html (垂直打开三个文件)

二、核心模式:vi 高效之魂

vi 的操作围绕几个不同的模式展开,这是初学者最需要适应的地方。

模式进入方式退出方式用途
普通模式 (Normal)启动默认模式,或按 <Esc>(无需退出)浏览、移动光标、执行命令。这是核心模式,大部分时间都在这里。
插入模式 (Insert)i, I, a, A, o, O<Esc>输入和编辑文本。就像使用普通文本编辑器一样。
可视模式 (Visual)v, V, Ctrl+v<Esc>选择文本块,以便进行后续操作(复制、删除、缩进等)。
命令行模式 (Ex):执行后自动退出或按 <Esc>执行保存、退出、搜索替换等高级命令

三、常用命令与组合(按场景分类)

以下命令在普通模式下使用(除非指定在命令行模式)。

1. 光标移动 (Navigation) - 脱离方向键
命令功能场景
h, j, k, l左,下,上,右基础移动,实现手不离主键盘区
w, b移动到下一个/上一个单词开头在代码或英文文本中快速跳跃
0, $移动到行首/行尾快速定位到行首行尾
gg, G移动到文件开头/末尾快速浏览长文件
[n]G:[n]跳转到第 n 行配合编译错误信息快速定位
Ctrl+u, Ctrl+d向上/向下翻半页快速滚动页面
Ctrl+f, Ctrl+b向下/向上翻一页快速滚动页面
%, ({, })在匹配的括号间跳转检查代码块,快速找到匹配的 {} () []
2. 文本编辑 (Editing)
命令功能场景
i, a在光标前/后插入 (Insert/Append)开始编辑文本
I, A在行首/行尾插入快速在行首/尾添加内容
o, O在下方/上方开辟新行 (Open line)快速插入新行
x, dw, dd删除字符/单词/整行 (Delete)基础删除操作
D删除从光标到行尾快速清空行尾
r替换单个字符 (Replace)快速修正拼写错误
cw修改单词 (Change Word)删除一个单词并进入插入模式,高效重命名
u, Ctrl+r撤销/重做 (Undo/Redo)必备操作
J将下一行连接到当前行尾 (Join)合并两行
.重复上一个编辑操作vi 的超级武器,高效执行重复性修改
3. 复制、粘贴与选择 (Yank, Put, Visual)
命令功能场景
yw, yy复制单词/整行 (Yank)复制操作
p, P在光标后/前粘贴 (Put)粘贴操作
v进入字符可视模式选择任意文本块
V进入行可视模式按行选择文本
Ctrl+v进入块可视模式列编辑神器,同时操作多行
y, d(在可视模式下) 复制/删除选中的内容对选中的文本执行操作
4. 搜索与替换 (Search & Replace)
命令 (模式)功能场景
/pattern向前搜索 pattern查找内容
?pattern向后搜索 pattern反向查找
n, N跳转到下一个/上一个匹配项在搜索结果间快速跳转
:%s/old/new/g (命令行)全局替换 (Substitute)将文件中所有 old 替换为 new
:%s/old/new/gc (命令行)全局替换,每次确认安全替换,避免误操作
:10,20s/old/new/g (命令行)在特定行范围(10-20)内替换精确替换
5. 文件与窗口操作 (File & Window)
命令 (模式)功能场景
:w保存文件 (Write)保存当前文件
:q退出 vi (Quit)退出当前窗口
:wqZZ保存并退出最常用的退出方式
:q!不保存强制退出放弃所有修改
:e filename打开另一个文件 (Edit)在不退出vi的情况下编辑新文件
:sp [filename]水平分割窗口 (Split)同时查看或编辑两个文件(上下)
:vsp [filename]垂直分割窗口 (Vertical Split)同时查看或编辑两个文件(左右)
Ctrl+w w在窗口间循环切换多窗口编辑时切换焦点
:ls列出所有缓冲区(打开的文件)查看已打开的文件列表
:bn, :bp切换到下一个/上一个缓冲区在多个打开的文件间切换

四、常用组合与实战场景

1. 高效代码编辑
# 组合1:快速注释/取消注释多行代码(块可视模式)
1. 按 `Ctrl+v` 进入块可视模式。
2. 用 `j/k` 选择要注释的行。
3. 按 `I`(大写i),输入注释符(如 `#``//`)。
4. 按 `<Esc>`,所选所有行首都会自动添加注释符。

# 组合2:快速复制/删除一个函数
1. 将光标移动到函数开始的 `{`2. 按 `v%`:进入可视模式并选中到匹配的 `}`3. 按 `y` 复制或 `d` 删除。

# 组合3:重命名变量(利用 `*` 搜索和 `cw`)
1. 将光标移到变量名上。
2. 按 `*` 搜索下一个相同的变量。
3. 按 `cw`,输入新变量名,按 `<Esc>`4. 按 `n` 找到下一个,按 `.` 重复上一次的修改操作。
2. 系统管理(编辑配置)
# 组合1:快速定位并修改配置
vi +/^PORT /etc/service.conf # 打开文件并直接跳到以PORT开头的行

# 组合2:安全地全局替换(先检查,再替换)
:%s/old_hostname/new_hostname/gc # 每次替换前都会询问确认

# 组合3:同时编辑多个相关配置
vi -O /etc/nginx/nginx.conf /etc/nginx/sites-available/default
# 垂直分屏打开两个配置文件,方便对照修改
3. 日志查看与分析
# 组合1:只读模式查看大日志,防止误触
view /var/log/syslog # 或 vi -R

# 组合2:跳转到日志文件末尾,实时查看新增内容
vi + /var/log/app.log # 打开后,按 `G` 跳转到文件末尾

# 组合3:在日志中搜索特定错误,并高亮显示(vim)
vim +'/ERROR|WARN' +'set hlsearch' /var/log/app.log
# 打开文件,搜索ERROR或WARN,并开启搜索高亮

五、配置优化 (~/.vimrc)

要真正发挥 vim 的威力,需要配置 ~/.vimrc 文件。一些基础设置:

set number          " 显示行号
syntax on           " 开启语法高亮
set tabstop=4       " Tab键宽度为4空格
set shiftwidth=4    " 自动缩进宽度为4空格
set expandtab       " 将Tab转换为空格
set hlsearch        " 高亮显示搜索结果
set incsearch       " 输入搜索模式时就显示匹配点
set mouse=a         " 启用鼠标支持(在支持鼠标的终端中)

总结:vi/vim 哲学

  1. 模式是核心:大部分时间停留在普通模式,按需短暂进入插入模式,完成后迅速返回 <Esc>
  2. 命令可组合[次数][命令][范围/文本对象]。例如:
    • d2w (Delete 2 Words):删除 2 个单词。
    • c$ (Change to end of line):修改从光标到行尾的内容。
    • 5yy (Yank 5 lines):复制 5 行。
  3. . 命令是神器:它可以重复任何编辑操作,是自动化简单重复任务的终极武器。

7️⃣awk命令 – 文本分析

awk 是 Linux 中最强大、最灵活的文本处理工具之一,它不仅仅是一个命令,更是一门完整的编程语言,专门设计用于处理结构化文本数据(如日志、CSV、表格数据等)。

它的核心思想是:逐行扫描文件,根据指定的模式匹配条件,执行对应的动作。其基本语法为:
awk 'pattern { action }' input_file


一、核心参数详解与使用场景

参数全称/含义使用场景示例
-F fs--field-separator fs (字段分隔符)指定输入文件的字段分隔符。这是最常用的参数,默认为空格和TAB。awk -F: '{print $1}' /etc/passwd (用 : 分隔) awk -F'[, ]' '{print $2}' file (使用多个分隔符)
-v var=value--assign var=value (变量赋值)在 awk 脚本开始执行前,定义一个变量并赋值。用于从外部向 awk 脚本传递参数。awk -v name="Alice" '{print name, $1}' file.txt
-f script-file--file script-file (文件)从脚本文件中读取 awk 命令,而不是在命令行中输入。用于执行复杂、冗长的 awk 脚本。awk -f process_data.awk input.txt
-W option(GNU awk 扩展选项)提供 GNU awk (gawk) 特有的扩展功能。awk -W interactive (交互式模式) awk -W version (显示版本)

二、awk 内置变量与特殊模式

理解这些内置变量是掌握 awk 的关键。

变量/模式含义使用场景
$0当前行的全部内容打印或处理整行
$1, $2, ..., $NF当前行的第1, 2, …, 最后一个字段处理列数据,NF 是字段总数
NF当前行的字段数量 (Number of Fields)print $NF 打印最后一个字段;$(NF-1) 打印倒数第二个
NR当前处理的行号 (Number of Records)NR==1 处理第一行(表头);NR>=10 处理10行以后
FNR当前文件的行号 (File Number of Records)处理多个文件时,每个文件的行号独立计数
FS输入字段分隔符 (Field Separator)等同于 -F 参数,可在 BEGIN 块中设置,如 BEGIN{FS=":"}
OFS输出字段分隔符 (Output Field Separator)控制 print 输出时各字段间的分隔符,如 BEGIN{OFS="->"}
RS输入记录(行)分隔符 (Record Separator)默认为换行符,可修改为其他字符(如处理段落)
ORS输出记录(行)分隔符 (Output Record Separator)控制 print 输出时的行结束符,默认为换行符
BEGIN{}特殊模式,在处理任何输入行之前执行一次初始化变量、打印表头、设置分隔符
END{}特殊模式,在处理完所有输入行之后执行一次打印汇总信息、计算结果

三、常用组合与实战场景

1. 字段提取与打印(最常用场景)
# 1. 打印指定的列(类似 cut 命令)
awk '{print $1, $3}' file.txt          # 打印第1和第3列(默认空格分隔)
awk -F, '{print $2 " - " $5}' data.csv # 打印CSV文件的第2和第5列,用" - "连接

# 2. 打印最后一列和倒数第二列
awk '{print $NF, $(NF-1)}' file.txt

# 3. 交换两列的位置
awk '{print $2, $1, $3}' file.txt      # 交换第1和第2列

# 4. 格式化输出(类似 printf)
awk '{printf "Name: %-10s Score: %03d\n", $1, $2}' scores.txt
# %-10s: 左对齐,宽度10的字符串
# %03d: 宽度3,不足补0的数字
2. 模式过滤与条件处理(类似 grep + 逻辑判断)
# 1. 打印匹配模式的行(类似 grep)
awk '/error/ {print $0}' system.log    # 打印包含 "error" 的行
awk '!/debug/ {print}' app.log         # 打印不包含 "debug" 的行({print} 是默认动作,可省略)

# 2. 基于字段值的过滤(这才是awk的威力所在)
awk '$3 > 100 {print $1, $3}' data.txt # 打印第3列值大于100的行的第1和第3列
awk '$1 == "root" {print}' /etc/passwd # 打印第1列为 "root" 的行
awk '$2 ~ /^[0-9]+$/ {print}' file     # 打印第2列是数字的行(~ 表示匹配正则)

# 3. 组合条件 (&&, ||, !)
awk '$3 > 50 && $4 == "YES" {print NR, $0}' file # 逻辑与
awk 'NR>=10 && NR<=20 {print}' large_file.txt    # 打印10到20行(类似 sed -n)
3. 计算与统计(awk 是计算器)
# 1. 数值计算(对某一列求和、求平均值、找最大值等)
awk '{sum += $3} END {print "Total: ", sum}' data.txt        # 对第3列求和
awk '{sum += $3; count++} END {print "Avg: ", sum/count}' data.txt # 求平均值
awk 'max < $3 {max = $3} END {print "Max: ", max}' data.txt  # 找最大值
awk 'NR==1 {min=$3} $3 < min {min=$3} END {print "Min: ", min}' data.txt # 找最小值

# 2. 计数(统计出现次数,类似 sort | uniq -c)
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log
# 上面是“王牌命令”:统计第一列(假设是IP)的出现次数,用于分析日志来源IP

# 3. 统计不同状态码的出现次数
awk '{status_code=$9; count[status_code]++} END {for (s in count) print s, count[s]}' access.log
4. 文本处理与转换
# 1. 连接多个字段
awk '{print $1 "-" $2 "-" $3}' file.txt
# 或者使用OFS
awk 'BEGIN{OFS="-"} {print $1, $2, $3}' file.txt

# 2. 条件赋值与修改
awk '$3 > 100 {$4 = "High"; print}' data.txt # 如果第3列>100,则设置第4列为"High"并打印

# 3. 处理表头(跳过第一行)
awk 'NR>1 {print $1, $3}' with_header.csv    # 不处理标题行
5. 多文件处理与高级用法
# 1. 处理多个文件
awk '{print FILENAME, FNR, $0}' file1.txt file2.txt # 打印内容,并显示文件名和行号

# 2. 使用外部变量(-v 参数)
threshold=50
awk -v thr=$threshold '$3 > thr {print}' data.txt # 使用shell变量$threshold

# 3. 从文件读取脚本(-f 参数)
# 将复杂的awk逻辑写在 script.awk 文件中
# script.awk 内容:
#   BEGIN {FS=","; print "Report Start"}
#   $3 > 100 {print $1, $3}
#   END {print "Report End"}
awk -f script.awk input.csv

四、生产力提升技巧与组合

1. 日志分析经典组合
# 分析Nginx访问日志,统计访问最频繁的10个IP
awk '{ip_count[$1]++} END {for (ip in ip_count) print ip_count[ip], ip}' access.log | sort -nr | head -10

# 统计每个URL的访问次数
awk '{url_count[$7]++} END {for (u in url_count) print url_count[u], u}' access.log | sort -nr

# 计算平均响应大小(假设第10列是响应字节数)
awk '{sum += $10; count++} END {print "Avg Response Size: ", sum/count/1024, "KB"}' access.log
2. 系统监控命令
# 监控当前最耗CPU的进程(结合ps)
ps aux | awk '$3 > 10.0 {print $0}' # 显示CPU使用率超过10%的进程

# 检查磁盘使用率(结合df)
df -h | awk '$5+0 > 80 {print $1, $5}' # 显示使用率超过80%的分区
3. 数据清洗与格式化
# 将CSV文件转换为JSON(简易版)
awk -F, 'BEGIN{print "["} NR>1{printf "  {\"name\": \"%s\", \"id\": %s},\n", $1, $2} END{print "]"}' data.csv

# 过滤空白行和注释行
awk 'NF && !/^#/ {print}' config.conf # NF非空(有字段)且不以#开头

五、总结:awk 思维导图

  1. 选择数据源:文件或管道输入。
  2. 设置条件 (Pattern)
    • 行号:NR == 1
    • 正则:/error/
    • 字段值:$3 > 100
    • 组合:NR>10 && $2 ~ /pattern/
    • 特殊:BEGIN, END
  3. 执行动作 (Action)
    • 输出print, printf
    • 计算sum += $n
    • 统计count[$n]++
    • 流程控制if (...) {...} else {...}, for (key in array) {...}
  4. 处理结果:输出到屏幕、重定向到文件或通过管道传递给其他命令(如 sort)。

黄金法则

  • 对于基于列的操作、计算和复杂统计awk 是无可争议的王者。
  • 结合 BEGINEND 块,你可以完成从初始化到生成报告的全流程。
  • awk '{count[$x]++} END {for(i in count)...}' 是统计分析万能钥匙,务必掌握。

8️⃣sort命令 - 排序

sort 命令是 Linux 中用于对文本行进行排序的终极工具。它看似简单,但功能异常强大,尤其擅长处理结构化数据(如日志、CSV 文件等),并且是命令行管道中不可或缺的一环。

以下是 sort 命令的参数详解、使用场景和经典组合。


一、核心参数详解与使用场景

1. 排序规则控制(决定如何排序)
参数全称/含义使用场景示例
-n--numeric-sort (数字排序)按数值大小而非字符串顺序进行排序。这是最关键的参数之一,避免出现 10 排在 2 前面的情况。sort -n file.txt (按数字排)
-r--reverse (逆序)逆序输出排序结果(默认升序,-r 为降序)。sort -nr file.txt (数字降序)
-f--ignore-case (忽略大小写)排序时忽略字母大小写。将 Aa 视为相同。sort -f languages.txt
-u--unique (去重)在排序的同时,去除重复的行。相当于 sort | uniq,但更高效。sort -u duplicates.txt
2. 键定义(指定排序列,核心功能)
参数全称/含义使用场景示例
-k, --key=KEYDEF(指定排序键)指定排序所依据的字段(列)范围KEYDEF 格式为 F[.C][OPTS][,F[.C][OPTS]]。这是 sort 最强大的功能。sort -k2,2n data.txt (以第2列为键数字排序)
-t, --field-separator=SEP(指定分隔符)指定用于分隔字段的字符。默认是空格和TAB。必须与 -k 参数配合使用。sort -t',' -k3,3n data.csv (用逗号分隔,按第3列数字排序)

KEYDEF 格式详解 (-k):

  • F:字段编号(从1开始)。
  • .C:从该字段的第 C 个字符开始比较(可选,默认为1)。
  • OPTS:一个或多个排序选项(如 n, r),覆盖全局选项。
  • ,F[.C][OPTS]:指定键的结束位置。如果只指定起始字段,键会延伸到行尾最佳实践是明确指定起始和结束字段,如 -k2,2
3. 其他实用参数
参数全称/含义使用场景示例
-o, --output=FILE(输出文件)将排序结果输出到指定文件。可以安全地用于原地排序(即覆盖原文件),而 sort file > file 会导致文件清空。sort -o sorted.txt unsorted.txt
-c, --check(检查)检查文件是否已排序。如果未排序,则报告错误并退出状态为1。用于脚本中的验证。sort -c file.txt && echo "Sorted" || echo "Unsorted"
-s, --stable(稳定排序)进行稳定排序。保留所有相等输入行的原始顺序。当排序算法不稳定时有用。sort -s -k1,1 file
-h, --human-numeric-sort(人类可读数字)比较人类可读的数字(如 2K, 1G。用于排序 du -h, ls -lh 的输出。du -h | sort -h
-V, --version-sort(版本号排序)对文本中的版本号进行自然排序。能正确排序 v1.2, v1.10, v2.1sort -V version_list.txt
-S, --buffer-size=SIZE(缓冲区大小)指定使用的内存大小。用于优化大文件排序性能。sort -S 50% file (使用50%内存) sort -S 2G file (使用2GB内存)

二、常用组合与实战场景

1. 基础排序
# 1. 按字典序(默认)排序
sort names.txt

# 2. 按数字排序(处理纯数字列)
sort -n numbers.txt

# 3. 按数字降序排序
sort -nr numbers.txt

# 4. 排序并去重(非常常用)
sort -u emails.txt
# 等效于
sort emails.txt | uniq
2. 基于列(字段)的排序(处理表格数据)

这是 sort 最强大的功能,用于处理 ls -l, ps, 日志、CSV 等任何结构化输出。

# 1. 按第二列的数字大小进行排序(例如,ps输出的PID列)
ps aux | sort -nk 2

# 2. 按第三列的数字大小进行降序排序(例如,du输出的容量列)
du -sk * | sort -nrk 1
# 注意:因为du -sk输出只有两列,所以第一列就是大小

# 3. 处理CSV文件:按第3列(数字)排序,使用逗号分隔
sort -t',' -k3,3n data.csv

# 4. 指定复杂的多级排序规则
# 先按第2列数字排序(主键),如果相同,再按第1列字典序逆序排序(次键)
sort -k2,2n -k1,1r data.txt

# 5. 处理ls -l的输出:按文件大小(第5列)降序排序
ls -l | sort -nrk 5,5

# 6. 按文件扩展名排序(例如,取最后一个点之后的字符)
ls | sort -t'.' -k2,2
3. 系统监控与性能分析
# 1. 找出最耗内存的10个进程
ps aux | sort -rnk 4 | head -10
# 第4列是 %MEM

# 2. 找出最耗CPU的10个进程
ps aux | sort -rnk 3 | head -10
# 第3列是 %CPU

# 3. 按大小排序当前目录下的文件和目录(人类可读格式)
du -sh * | sort -h
# 这是 -h 参数的经典应用场景

# 4. 查看最大的5个日志文件
find /var/log -name "*.log" -exec du -h {} \; | sort -hr | head -5
4. 数据清洗与预处理
# 1. 检查配置文件是否已按特定键排序(例如,用于后续的join或diff)
sort -c -k1,1 config.txt

# 2. 对两个文件进行排序,为后续比较或合并做准备
sort -o file1.sorted.txt file1.txt
sort -o file2.sorted.txt file2.txt
diff file1.sorted.txt file2.sorted.txt

# 3. 为 `uniq -c` 准备数据(uniq要求输入已排序)
cat words.txt | sort | uniq -c | sort -nr
# 这个组合是“统计词频”的王牌命令:
# 1. sort: 将相同词排在一起
# 2. uniq -c: 计数并去重
# 3. sort -nr: 按计数结果(数字)降序排序,得到最高频的词
5. 高级用法与组合
# 1. 版本号排序(对打包和开发极其有用)
cat versions.txt
# v1.0
# v1.10
# v1.2
# v2.0
sort -V versions.txt # 会正确排序为 v1.0, v1.2, v1.10, v2.0

# 2. 指定特定字符范围作为键(例如,从第3个字符开始比较)
sort -k1.3,1.5 data.txt # 对每行第一个字段的第3到第5个字符进行排序

# 3. 安全地原地排序文件(使用 -o 参数,不要用重定向!)
sort -o large_file.txt large_file.txt # 正确做法
# sort large_file.txt > large_file.txt # 错误做法!会清空文件!

三、sortuniq 的黄金组合

sortuniq 是天生的一对,uniq 依赖于已排序的输入。

目标命令组合说明
去重sort file | uniq基本去重
显示唯一行sort file | uniq -u只显示从未重复的行
显示重复行sort file | uniq -d只显示重复过的行
统计出现次数sort file | uniq -c计数并去重
统计并排序次数sort file | uniq -c | sort -nr经典组合:统计频率并排序

示例:分析 Web 日志

# 统计访问最频繁的10个IP地址
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# 统计最受欢迎的10个URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

四、总结与最佳实践

  1. 始终用 -n 处理数字:除非你明确希望进行字符串排序(10 < 2),否则对数字列使用 -n
  2. 明确指定键范围:使用 -k2,2 而不是 -k2,避免键意外地延伸到行尾。
  3. 原地排序用 -o:要对文件自身排序时,永远使用 sort -o file file,不要用 sort file > file
  4. 管道组合是精髓sort 很少单独使用,它与 awk(提取列)、uniq(去重计数)、head/tail(取结果)等命令的组合能解决绝大多数数据分析问题。
  5. 性能优化:处理超大文件时,使用 -S 调整缓冲区大小可以显著提升速度。

决策流程图:
在这里插入图片描述


9️⃣uniq命令 - 去重

uniq 命令是 Linux 中用于报告或忽略重复行的实用工具。它通常与 sort 命令结合使用,因为 uniq 的一个关键特性是:它只能检测相邻的重复行

这意味着输入必须预先排序,才能正确去除所有重复项。


一、核心参数详解与使用场景

参数全称/含义使用场景示例
-c--count (计数)在每行前面加上该行重复出现的次数。这是最常用的参数,用于统计频率。uniq -c file.txt
-d--repeated (重复)仅显示重复出现的行(每组重复行只显示一次)。用于快速找出所有重复项。uniq -d file.txt
-u--unique (唯一)仅显示出现一次的行。用于找出所有独一无二的项,过滤掉所有重复项。uniq -u file.txt
-i--ignore-case (忽略大小写)在比较时忽略大小写。将 Hellohello 视为相同的行。uniq -i case_sensitive.txt
-f N--skip-fields=N (跳过字段)跳过每行前面的 N 个字段(由空格/TAB分隔)后再进行比较。用于忽略行首的无关信息(如时间戳、IP)。uniq -f 2 log.txt (跳过前2列)
-s N--skip-chars=N (跳过字符)跳过每行前面的 N 个字符后再进行比较。用于忽略固定的前缀(如行号)。uniq -s 5 data.txt (跳过前5个字符)
-w N--check-chars=N (检查字符)只比较每行前面的 N 个字符。用于只关心行首特定标识符(如用户名、错误码)是否重复的场景。uniq -w 3 codes.txt (只比较前3个字符)

二、常用组合与实战场景

uniq 的强大之处几乎完全体现在与 sort 和其他命令的组合中。

1. 统计分析与计数(最常用场景)
# 1. 统计文件中每行内容的出现次数(经典组合:sort | uniq -c)
sort names.txt | uniq -c
# 输出示例:
#       3 Alice
#       5 Bob
#       2 Charlie

# 2. 按出现频率从高到低排序(另一个经典组合)
sort names.txt | uniq -c | sort -nr
# 输出示例:
#       5 Bob
#       3 Alice
#       2 Charlie

# 3. 找出最常用的10个命令(分析命令行历史)
history | awk '{print $2}' | sort | uniq -c | sort -nr | head -10
2. 数据清洗与去重
# 1. 基本去重(必须先排序!)
sort duplicates.txt | uniq > unique_items.txt

# 2. 直接使用 sort 的 -u 参数(效果等同,更简洁)
sort -u duplicates.txt > unique_items.txt

# 3. 仅找出重复项(例如,找出重复的订单号、用户ID)
sort order_ids.txt | uniq -d

# 4. 仅找出唯一项(例如,找出只出现过一次的异常错误)
sort errors.log | uniq -u
3. 日志分析(结合 -f 参数跳过字段)

日志文件通常带有时间戳、IP等前缀,-f 参数非常有用。

# 假设日志格式: [Timestamp] [LogLevel] Message
# 示例行: [2023-10-27 10:00:01] [ERROR] Database connection failed

# 1. 跳过前2个字段(时间戳和日志级别),只对错误信息本身进行统计
sort app.log | uniq -f 2 -c
# 这会统计每种错误信息出现的次数,而不管它是什么时间发生的

# 2. 分析Nginx访问日志,统计每种HTTP状态码的出现次数
awk '{print $9}' access.log | sort | uniq -c
# $9 是状态码所在的列

# 3. 统计每个IP的访问次数(Web日志分析经典命令)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
4. 高级文本处理(结合其他命令)
# 1. 比较两个文件(找出只在file1中出现的行)
sort file1.txt file2.txt | uniq -u
# 注意:这实际上会找出两个文件中所有唯一的行。正确做法是:
comm -23 <(sort file1.txt) <(sort file2.txt) # 推荐用 comm 命令

# 2. 忽略大小写进行去重(例如,处理用户输入的标签)
sort -f tags.txt | uniq -i

# 3. 检查代码中重复的函数定义(粗略检查)
grep -r '^def ' /path/to/code/ | sort | uniq -d

三、uniqsort -u 的区别

这是一个常见问题。两者都能去重,但有重要区别:

特性sort -usort | uniq
功能排序并去重排序后去重
输出排序后的唯一行排序后的唯一行
灵活性较低。只能去重。极高。可与 uniq -c, uniq -d, uniq -u 等参数组合,实现计数、找重复、找唯一等功能。
性能稍快,一次处理完成稍慢,需要两个命令通过管道连接
使用场景简单的去重需求复杂的去重和统计分析需求

结论:如果只是简单地去重,sort -u 更简洁。如果需要统计次数、仅找重复项或唯一项,必须使用 sort | uniq 组合。


四、注意事项与常见误区

  1. 输入必须已排序:这是最重要的原则。uniq 无法检测不相邻的重复行。

    • 错误示范uniq unsorted_file.txt (结果不可预测)
    • 正确做法sort file.txt | uniq
  2. 理解“字段”和“字符”

    • -f N:跳过由空格/TAB分隔的前 N 个字段
    • -s N:跳过前 N 个字符(无论是什么)。
  3. 参数可以组合:例如,uniq -ic 可以同时实现忽略大小写并计数。

五、常用组合速查表

场景命令组合说明
统计词频sort file | uniq -c统计每行出现次数
按频率排序sort file | uniq -c | sort -nr王牌组合,列出最高频项
找出重复项sort file | uniq -d只显示重复的行
找出唯一项sort file | uniq -u只显示不重复的行
忽略前缀去重sort file | uniq -f N跳过前N列后比较
忽略大小写去重sort -f file | uniq -i将大小写视为相同

总结uniq 本身很简单,但其价值在与其他命令(尤其是 sort)的组合中得以无限放大。掌握 sort | uniq -c | sort -nr 这个统计黄金管道,你就能高效地分析日志、统计数据和进行各种文本挖掘工作。


🔟cut命令 - 裁剪列

cut 命令是 Linux 中一个简单而高效的文本处理工具,它的核心功能是按“列”提取文本内容。它特别擅长处理具有固定分隔符或固定字符位置的规整文本数据。

与功能更强大的 awk 相比,cut 更加轻量和专注,是快速提取字段的利器。


一、核心参数详解与使用场景

cut 主要提供三种方式来定义要提取的“列”。

参数全称/含义使用场景示例
-f, --fields=LIST(字段)指定要提取的字段(列),基于分隔符。这是最常用的参数。LIST 可以是单个数字、逗号分隔的列表或范围(如 1,3,51-3)。cut -f1,3 file.txt (提取第1和第3列)
-d, --delimiter=DELIM(分隔符)指定用于分隔字段的分隔符。默认是TAB字符。必须与 -f 参数配合使用cut -d',' -f2 data.csv (用逗号分隔,提取第2列)
-c, --characters=LIST(字符)指定要提取的字符位置(按字符数),而不是字段。用于处理固定宽度的文本或从每行特定位置提取数据。cut -c1-5,10-15 file.txt (提取1-5和10-15的字符)
--complement(补集)提取指定字段或字符范围之外的所有内容。相当于“反选”。cut -f3 --complement file (提取除第3列外的所有列)
-s, --only-delimited(仅分隔行)不打印不包含分隔符的行。用于过滤掉那些格式不规范、无法被 -d-f 处理的无效行。cut -d':' -f1 -s /etc/passwd (只处理包含冒号的行)

LIST 格式说明:

  • N:第 N 个字段/字符(从 1 开始计数)
  • N-:从第 N 个到行尾
  • N-M:从第 N 个到第 M 个(包含)
  • -M:从第 1 个到第 M 个
  • 组合:N,M,PN-M,P-Q

二、常用组合与实战场景

1. 处理基于分隔符的文件(-d 与 -f 组合)

这是 cut 最核心的用途,尤其适用于 CSV、TSV 或类似 /etc/passwd 的系统配置文件。

# 1. 提取 /etc/passwd 文件中的用户名(第1列,冒号分隔)
cut -d':' -f1 /etc/passwd

# 2. 提取 CSV 文件中的第1和第3列
cut -d',' -f1,3 data.csv

# 3. 提取命令输出的特定列(例如,提取 ps 输出的进程ID和命令)
ps aux | cut -d' ' -f1,11-  # 注意:空格分隔可能不规整,有局限性
# 更好的方式通常是使用 awk: `ps aux | awk '{print $1, $11}'`

# 4. 提取一个范围列(例如,第2列到最后一列)
cut -d' ' -f2- logfile.txt

# 5. 排除某一列(例如,提取除第2列外的所有列)
cut -d',' -f2 --complement data.csv
2. 处理固定宽度的文本(-c 参数)

适用于处理旧式系统日志、特定格式的输出或固定长度的字符串。

# 1. 提取每行的前10个字符
cut -c1-10 file.txt

# 2. 提取每行的第5到第15个字符
cut -c5-15 file.txt

# 3. 提取单个字符位置(例如,每行的第一个字符)
cut -c1 file.txt

# 4. 结合其他命令(例如,检查文件权限位)
ls -l | cut -c1-10  # 提取类似 '-rwxr-xr-x' 的权限字符串
3. 系统管理与日志分析
# 1. 快速查看磁盘使用率最高的分区(结合 sort 和 head)
df -h | sort -hr -k5 | head -5 | cut -d' ' -f1,5
# 先按使用率排序,再提取分区名和使用率列

# 2. 分析日志,提取时间戳和错误信息(假设时间戳是前15个字符)
cut -c1-15 system.log | sort | uniq -c  # 统计每分钟的日志量

# 3. 获取当前主机的IP地址(方法之一)
hostname -I | cut -d' ' -f1  # 第一个IP地址通常是主IP
4. 数据清洗与预处理
# 1. 提取电子邮件地址的用户名部分(@之前)
echo "user@example.com" | cut -d'@' -f1

# 2. 提取文件名的后缀
echo "document.pdf" | cut -d'.' -f2

# 3. 提取文件名的前缀(对于包含多个点的情况可能不准)
echo "archive.tar.gz" | cut -d'.' -f1
# 这种情况下,使用变量扩展或awk更可靠:${filename%%.*}

# 4. 过滤掉文件中的注释(假设注释以#开头,但不在行首无效)
grep -v '^#' config.cfg | cut -d'#' -f1
# 先删除整行注释,再截取行内注释之前的内容

三、cut 的局限性及替代方案

cut 简单高效,但也有明显缺点。了解何时该用 cut,何时该换用其他工具(如 awk)非常重要。

场景cut 的表现更好的替代方案(通常是 awk
分隔符是空格很差。无法处理连续的空格,会将每个空格都视为分隔符,导致列号错乱。awk '{print $1}'。awk 默认会将连续的空格/制表符压缩为一个分隔符。
字段顺序不固定无法处理。依赖固定的列号。awk -F':' '{print $NF}'。可以使用 $NF(最后一列)等相对位置。
需要格式化输出无法实现。只能简单拼接提取的字段。awk -F':' '{printf "User: %-10s UID: %s\n", $1, $3}' /etc/passwd
基于模式提取无法实现。只能按位置提取。awk -F':' '$3 > 1000 {print $1}' /etc/passwd (提取普通用户)
重新排列字段顺序可以实现,但很繁琐。cut -f3,1,2awk -F',' '{print $3, $1, $2}' OFS=',' data.csv (更直观)

简单决策指南:

  • 数据规整,分隔符是单字符(非空格),只需按位置提取 -> cut (最快最简)
  • 数据复杂,分隔符是空格,或需要判断、计算、格式化 -> awk (功能最强)

四、常用组合速查表

场景命令组合说明
提取系统用户名cut -d: -f1 /etc/passwd经典示例,冒号分隔取第1列
提取CSV特定列cut -d, -f2,4 data.csv逗号分隔,取第2和第4列
提取字符范围cut -c1-10 file.txt提取每行前10个字符
排除某一列cut -f3 --complement file提取除第3列外的所有列
过滤无效行cut -d':' -f1 -s file只处理包含分隔符的行
管道提取ps aux | cut -d' ' -f1,11从命令输出中提取列(注意空格问题)

总结

cut 是一个专注的工具,它的优势在于简单和速度。对于处理结构清晰的文本数据(如 CSV、TSV、/etc/passwd),它是一个无可替代的快速解决方案。

记住它的核心组合:

  • -d + -f:用于分隔符明确的列
  • -c:用于固定字符位置的列

当遇到 cut 无法处理的复杂场景时,不要犹豫,请毫不犹豫地请出它的“老大哥”——awk


0️⃣tr命令 - 字符替换

好的,tr (translate / transliterate) 是 Linux 中一个简单高效的命令,专门用于对来自标准输入的字符进行替换、压缩和删除。它不像 sedawk 那样功能全面,但正因为其专注,在处理纯字符层面的操作时,它往往更加快捷和简洁。

它的核心语法是:tr [OPTION]... SET1 [SET2]


一、核心参数详解与使用场景

参数全称/含义使用场景示例
(无参,SET1 SET2)(转换)将 SET1 中出现的字符替换为 SET2 中对应位置的字符。这是最基本的功能。tr 'abc' 'ABC' (a->A, b->B, c->C)
-d--delete (删除)删除所有属于 SET1 的字符tr -d '\r' (删除回车符 ^M)
-s--squeeze-repeats (压缩重复)将 SET1 中列出的重复字符压缩成一个tr -s ' ' (将多个连续空格压缩成一个)
-c / -C--complement (补集)操作对象是 SET1 的补集(即所有不属于 SET1 的字符)。tr -cd '0-9' (删除所有非数字字符)
预定义字符集 (用于 SET1 或 SET2)

tr 可以理解一些特殊的预定义集合,非常有用。

集合含义使用场景
'[:lower:]'所有小写字母tr '[:lower:]' '[:upper:]' (小写转大写)
'[:upper:]'所有大写字母tr '[:upper:]' '[:lower:]' (大写转小写)
'[:alpha:]'所有字母 (a-z, A-Z)tr -d '[:alpha:]' (删除所有字母)
'[:digit:]'所有数字 (0-9)tr -d '[:digit:]' (删除所有数字)
'[:alnum:]'所有字母和数字tr -c -d '[:alnum:]' (只保留字母和数字)
'[:space:]'所有空白字符 (空格, TAB, 换行等)tr -s '[:space:]' (压缩所有空白字符)
'[:punct:]'所有标点符号tr -d '[:punct:]' (删除所有标点)
'[:graph:]'所有可打印字符 (不含空格)
'[:print:]'所有可打印字符 (含空格)
'[:cntrl:]'所有控制字符

二、常用组合与实战场景

1. 字符转换 (最基本的替换)
# 1. 大小写转换 (非常常用)
echo "Hello World" | tr '[:lower:]' '[:upper:]'  # 输出: HELLO WORLD
echo "Hello World" | tr 'a-z' 'A-Z'              # 等效写法

# 2. 替换特定字符 (例如,将分隔符从空格替换为逗号)
echo "apple banana cherry" | tr ' ' ','          # 输出: apple,banana,cherry

# 3. 替换换行符 (例如,将多行合并为一行,用空格分隔)
cat multi_line.txt | tr '\n' ' '                 # 将所有换行符替换为空格
# 注意:这会在最后也加一个空格。更好的工具是 `paste -s` 或 `xargs`。

# 4. 创建简单的加密 (凯撒密码/ROT13)
echo "secret" | tr 'a-zA-Z' 'n-za-mN-ZA-M'       # 输出: frperg
echo "frperg" | tr 'a-zA-Z' 'n-za-mN-ZA-M'       # 输出: secret (解密)
2. 字符删除 (-d 参数)
# 1. 删除Windows文件中的回车符 (^M) - 经典用法!
# 从Windows拷贝文件到Linux后经常需要执行
cat file_from_win.txt | tr -d '\r' > clean_file.txt
# 或者直接修改文件
tr -d '\r' < file_from_win.txt > clean_file.txt

# 2. 删除所有数字
echo "My phone is 123-4567" | tr -d '[:digit:]'  # 输出: My phone is -

# 3. 删除所有标点符号
echo "Hello, World! How's it going?" | tr -d '[:punct:]' # 输出: Hello World Hows it going

# 4. 删除所有非数字字符 (提取纯数字)- 补集 + 删除的强大组合
echo "Phone: (123) 456-7890" | tr -cd '[:digit:]' # 输出: 1234567890
# -c '[:digit:]' 意思是“所有非数字字符”
# -d 意思是“删除”
# 合起来就是“删除所有非数字字符”,效果是只保留数字
3. 字符压缩 (-s 参数)
# 1. 压缩多余的空格 (非常常用,用于清理日志或文本)
echo "This    has   too    many spaces." | tr -s ' ' # 输出: This has too many spaces.

# 2. 压缩空行 (将多个连续换行符压缩成一个)
cat file_with_blanks.txt | tr -s '\n'            # 输出内容不变,但空行只剩一行

# 3. 压缩重复字符 (例如,删除重复的字母,虽然实用价值不大,但演示了功能)
echo "boooooooot" | tr -s 'o'                   # 输出: boot
4. 系统管理与实战组合

tr 经常和其他命令通过管道 (|) 组合,形成强大的单行脚本。

# 1. 生成随机密码 (结合 /dev/urandom)
# 取48字节随机数据,删除所有非字母数字字符,取前16个
head -c 48 /dev/urandom | tr -cd '[:alnum:]' | head -c 16; echo

# 2. 统计文本中不同单词的数量 (tr 处理,sort|uniq 统计)
cat novel.txt | tr -cs '[:alpha:]' '\n' | sort | uniq -c | sort -nr | head -10
# 分解:
#   tr -cs '[:alpha:]' '\n':
#     -c 补集:非字母字符
#     -s 压缩:将连续的匹配压缩成一个
#     整体效果:将所有非字母字符转换为换行符,并压缩多余的换行符。
#     最终效果:每个单词被放在单独的一行。
#   sort | uniq -c:排序并计数
#   sort -nr:按计数倒序排序
#   head -10:显示前10个

# 3. 检查代码中是否包含制表符 (用于强制空格风格的项目)
if cat -A code.py | grep '\^I' > /dev/null; then echo "Contains tabs!"; fi
# 更简单的方法:
if tr -d -c '\t' < code.py | wc -c > 0; then echo "Contains tabs!"; fi
# 分解:删除所有非制表符字符,然后计算剩余字符数。如果大于0,说明有制表符。

# 4. 格式化 ps 输出 (虽然awk更佳,但tr也是一种思路)
ps aux | tr -s ' ' | cut -d ' ' -f 1,2,11
# 先用 tr -s ' ' 压缩连续空格为单个空格,这样 cut 的列号就稳定了。

三、注意事项与局限性

  1. 不支持正则表达式tr 只能处理字面字符或字符类,不能使用 *, +, .* 等正则元字符。这是它与 sed 的主要区别。

    • trecho "hello" | tr 'l*' 'L' (会尝试将 l* 都替换成 L)
    • sedecho "hello" | sed 's/l*/L/g' (使用正则,匹配0个或多个l)
  2. 处理文件tr 不接受文件名作为参数,它只从标准输入读取。必须使用重定向 (<) 或管道 (|)。

    • 正确tr 'a-z' 'A-Z' < file.txt
    • 正确cat file.txt | tr 'a-z' 'A-Z'
    • 错误tr 'a-z' 'A-Z' file.txt (不会报错,但会忽略 file.txt,等待你从键盘输入)
  3. 字符集对应:如果 SET1SET2 长,SET2 的最后一个字符会被重复使用,以匹配 SET1 的长度。

    • echo "abc" | tr 'abcde' 'XY' => 输出 XYYa->X, b->Y, c->Y (最后一个字符Y被复用),de也被映射为Y但输入中没有。
  4. 字符范围:使用范围 like a-z 时要小心,因为它依赖于系统的字符集排序(locale),在某些语言环境下可能不会如你预期的那样工作。

四、总结:高频用法速查表

场景命令组合说明
大小写转换tr '[:lower:]' '[:upper:]'小写转大写
删除回车符tr -d '\r'处理Windows文本文件
压缩空格tr -s ' '多个空格变一个
提取数字tr -cd '[:digit:]'只保留数字,删除其他一切
替换分隔符tr ' ' '\n'空格替换为换行(一行变多行)
删除标点tr -d '[:punct:]'删除所有标点符号
生成随机串tr -cd '[:alnum:]' < /dev/urandom | head -c 16生成16位随机字母数字密码
单词分割tr -cs '[:alpha:]' '\n'将非字母字符全部转换为换行,用于单词统计

结论tr 是一个专注、高效的字符处理工具。对于简单的全局字符替换、删除和压缩任务,它是首选,速度往往比 sed 更快。对于涉及模式匹配(正则表达式)或更复杂逻辑的任务,则需要使用 sedawk。掌握 tr 能让你的命令行文本处理技巧更加精炼和高效。


1️⃣wc命令 - 计数

wc (word count) 命令是 Linux 中一个简单但极其实用的工具,用于统计文件或输入流中的行数、单词数和字节数。它是系统管理、日志分析和编程工作中进行快速统计的利器。

以下是 wc 命令的参数详解、使用场景和经典组合。


一、核心参数详解与使用场景

wc 的参数非常直观,每个参数对应一种统计维度。

参数全称/含义使用场景示例
-l--lines (行数)统计行数。这是最常用的参数,用于统计代码行数、日志条目数、文件数量等。wc -l file.txt
-w--words (单词数)统计单词数(以空格、TAB、换行符分隔的字符串)。用于粗略评估文档长度。wc -w essay.txt
-c--bytes (字节数)统计字节数。用于查看文件的确切大小(与 ls -l 看到的相同)。wc -c image.jpg
-m--chars (字符数)统计字符数。对于 ASCII 文本,与 -c 相同;对于 Unicode 文本(如中文),一个字符可能占多个字节。`echo “你好”
(无参数)同时显示行数、单词数、字节数和文件名。提供所有基本信息。wc report.txt

输出格式说明:
无论使用哪个参数,输出格式通常为:
行数 单词数 字节数 文件名

如果从标准输入读取数据,则不显示文件名。


二、常用组合与实战场景

wc 的真正威力在于与其他命令通过管道 (|) 组合,形成强大的统计单行脚本。

1. 代码与文档统计(最经典场景)
# 1. 统计一个源代码文件的总行数
wc -l main.c

# 2. 统计当前目录下所有 .py 文件的总行数(递归)
find . -name "*.py" -exec cat {} \; | wc -l
# 或者更高效的方法(避免启动多个cat进程):
find . -name "*.py" -print0 | xargs -0 wc -l

# 3. 分别统计每个 .py 文件的行数,并显示总计
wc -l *.py

# 4. 统计当前项目的总代码行数(只统计源代码,排除空行和注释)
find . -name "*.py" -exec cat {} \; | grep -v '^\s*$' | grep -v '^\s*#' | wc -l
# 分解:
#   grep -v '^\s*$':排除空行和只有空白字符的行
#   grep -v '^\s*#':排除以 # 开头的注释行(Python)
2. 系统管理与日志分析
# 1. 统计当前目录下的文件和目录总数(不包括隐藏文件)
ls -l | wc -l
# 注意:ls -l 的第一行是"总计"行,所以实际数量是 (wc -l 的结果 - 1)

# 2. 更准确的方法:使用 find
find . -maxdepth 1 -type f | wc -l # 只统计文件
find . -maxdepth 1 -type d | wc -l # 只统计目录(包括当前目录.)

# 3. 统计日志文件中的错误条目数
grep -i "error" /var/log/syslog | wc -l

# 4. 监控日志增长速度(每秒打印一次行数变化)
watch -n 1 'tail -n 100 app.log | wc -l'
3. 数据验证与处理
# 1. 比较两个文件的大小是否相同
if [ $(wc -c < file1.txt) -eq $(wc -c < file2.txt) ]; then
    echo "Files are the same size"
fi

# 2. 检查一个文件是否为空(行数为0)
if [ $(wc -l < config.cfg) -eq 0 ]; then
    echo "Config file is empty!"
fi

# 3. 计算文件的平均单词长度(awk辅助计算)
wc -ww file.txt | awk '{print $2 / $1}'
4. 创作与写作
# 1. 统计文章的总单词数(英文写作常用)
wc -w novel.txt

# 2. 统计Markdown文档的字符数(中英文混合)
wc -m README.md

# 3. 实时统计输入的字数(按Ctrl+D结束输入)
wc -w
# 然后开始输入内容,完成后按 Ctrl+D

三、重要注意事项与技巧

  1. -c-m 的区别

    • -c (bytes):文件在磁盘上占用的实际字节数。对于包含中文等非ASCII字符的UTF-8文本,一个字符可能占用2-4个字节。
    • -m (chars):文本中包含的字符数量。一个中文字符算一个。
    • 示例:一个包含 你好 两个字符和一個换行符的文本文件。
      echo "你好" > test.txt
      wc -c test.txt # 可能输出 7 (UTF-8编码中,每个中文3字节,加上换行符1字节:3+3+1=7)
      wc -m test.txt # 输出 3 (2个字符 + 1个换行符)
      
  2. 从标准输入读取:使用 < 重定向或管道 | 时,wc 不会输出文件名。

    wc -l < /etc/passwd  # 只输出一个数字:文件行数
    cat /etc/passwd | wc -l # 同上,但多创建一个进程,效率较低
    
  3. 处理大量文件:使用 xargs 避免 “Argument list too long” 错误。

    # 错误:文件太多时可能出错
    wc -l *.log
    # 正确:使用 find + xargs
    find . -name "*.log" -print0 | xargs -0 wc -l
    
  4. 统计文件数量:虽然 wc -l 常用于统计 lsfind 输出的行数来间接统计文件数,但有更可靠的工具:

    # 统计当前目录下的文件数(不包括隐藏文件和目录本身)
    find . -maxdepth 1 -type f | wc -l
    # 使用 awk 统计 ls -l 的有效行(更准确)
    ls -l | awk '/^-/{count++} END {print count}'
    

四、常用组合速查表

场景命令组合说明
统计代码行数find . -name "*.c" -exec cat {} \; | wc -l统计所有C文件总行数
统计错误日志数grep "ERROR" app.log | wc -l统计错误出现的次数
查看文件大小wc -c < file.iso查看文件的字节大小
统计单词数wc -w essay.txt统计文档中的单词数
统计目录文件数ls -l | wc -l粗略统计(行数-1)
统计字符数wc -m document.txt统计字符数(适用于中文)
统计每文件行数wc -l *.py统计每个Python文件的行数并显示总计

总结

wc 是一个专注、高效的统计工具。它的核心价值在于其简洁和可组合性

  • 记住三个核心参数-l (行数), -w (单词数), -c (字节数)。
  • 理解其定位wc 本身不筛选数据,它总是依赖于 find, grep, ls 等命令来提供需要统计的输入流。
  • 掌握王牌组合
    • find | xargs wc -l:统计大量文件的行数。
    • grep | wc -l:统计匹配模式的出现次数。
    • ls | wc -l:粗略统计文件数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值