常用Linux命令-三剑客(五)
1、grep 命令
grep(Global Regular Expression Print)是 Linux 中最强大的文本搜索工具。它用于在文件中查找匹配特定模式(字符串或正则表达式)的行,并将结果打印出来。
无论是排查日志、查找代码还是过滤命令输出,grep 都是必不可少的利器。
基本语法
grep [选项] "搜索模式" [文件...]
参数说明
| 参数 | 长选项 | 作用 | 记忆技巧 |
|---|---|---|---|
| -i | --ignore-case | 忽略大小写 | Ignore |
| -v | --invert-match | 反向匹配(排除) | InVert |
| -n | --line-number | 显示行号 | Number |
| -r | --recursive | 递归搜索目录 | Recursive |
| -c | --count | 仅显示匹配行数 | Count |
| -l | --files-with-matches | 仅显示文件名 | List files |
| -w | --word-regexp | 全词匹配 | Word |
| -E | --extended-regexp | 使用扩展正则 | Extended |
| -o | --only-matching | 只输出匹配的部分 | Only |
| --color | - | 高亮显示匹配项 | 视觉辅助 |
实际使用举例
#基础字符串搜索
grep "error" app.log
#忽略大小写
grep -i "error" app.log
#递归搜索目录
grep -r "main function" .
#显示行号
grep -n "timeout" config.yaml
# 输出: 15: connection_timeout: 30s
#反向选择。排除包含特定内容的行。例如:查看日志中非 INFO 级别的记录。
grep -v "INFO" app.log
#前后文显示
##-A 2:显示匹配行及后 2 行 (After)
##-B 2:显示匹配行及前 2 行 (Before)
##-C 2:显示匹配行及前后各 2 行 (Context)
grep -C 3 "Exception" error.log
#查找正在运行的进程
ps aux | grep nginx
#多重过滤
grep "error" app.log | grep -v "ignored"
grep 支持三种正则语法:
基本正则 (BRE):默认模式。
扩展正则 (ERE):使用 -E 或 egrep。
Perl 正则 (PCRE):使用 -P(功能最强,但并非所有系统都支持)。
| 需求 | 命令示例 | 说明 |
|---|---|---|
| 以...开头 | grep "^root" /etc/passwd | ^ 表示行首 |
| 以...结尾 | grep "bash$" /etc/passwd | $ 表示行尾 |
| 任意字符 | grep "r..t" file | . 匹配任意单个字符 |
| 或逻辑 | `grep -E "error | warning" log` |
| 数字匹配 | grep -E "[0-9]+" file | 匹配连续数字 |
| 空行 | grep "^$" file | 匹配空白行 |
# 使用 ERE 匹配 IP 格式
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log
#多重查找
#查找包含 "error" 或"critical"或 “fatal” 的行
grep -E "error|critical|fatal" app.log
# 查找既包含 "error" 又包含 "timeout" 的行
grep "error" app.log | grep "timeout"
# 查找包含 "error" 但不包含 "ignored" 的行
grep "error" app.log | grep -v "ignored"
2、sed 命令
sed(Stream EDitor,流编辑器)是 Linux 中用于处理文本流的强大工具。
与 vi/vim 等交互式编辑器不同,sed 是非交互式的。它逐行读取输入,根据指定的规则进行处理(如替换、删除、插入),然后将结果输出到标准输出或写入文件。
它是自动化脚本、批量修改配置文件和数据清洗的必备神器。
无论是排查日志、查找代码还是过滤命令输出,grep 都是必不可少的利器。
基本语法
sed [选项] '命令' 文件名
注意
默认行为:sed 不会直接修改原文件,而是将处理后的结果打印到屏幕(标准输出)。
原地修改:需使用 -i 选项。
参数说明
| 参数 | 长选项 | 作用 | 典型场景 |
|---|---|---|---|
| -n | --quiet / --silent | 静默模式。默认不输出任何内容,除非显式使用 p 命令打印。 | 配合 /pattern/p 仅提取匹配行,替代 grep。 |
| -i | --in-place | 原地修改文件。直接修改源文件,而不是输出到屏幕。⚠️ 高危 | 批量修改配置文件。Linux: sed -i 's/a/b/' file; Mac: sed -i '' 's/a/b/' file。 |
| -e | --expression | 指定脚本/命令。允许在命令行中指定多个操作。 | sed -e 'cmd1' -e 'cmd2' file。默认情况下可省略。 |
| -f | --file | 从文件读取脚本。当命令很长时,写入文件执行。 | sed -f script.sed input.txt。 |
| -E | --regexp-extended | 启用扩展正则表达式。支持 +, ?, ` | , ()` 等无需转 a 义。 |
| -r | (旧版 Linux) | 同 -E,GNU sed 旧版本用法。 | 现代 Linux 建议统一用 -E。 |
| -b | --binary | 以二进制模式打开文件(Windows/Cygwin 有用)。 | 处理非文本文件时保留换行符格式。 |
| -l N | --line-length | 指定 l 命令的行宽。 | 调试时查看不可见字符。 |
基本格式
s/旧字符串/新字符串/标志
- s:代表 substitute(替换)。
- /:分隔符(也可以用 |, #, @ 等,避免与路径冲突)。
- 标志:
- g (global):全局替换,替换行内所有匹配项(默认只替换每行第一个)。
- i (ignore case):忽略大小写。
- p (print):打印匹配行(常与 -n 配合)。
实际使用举例
#简单替换(每行第一个 "apple" 变为 "orange")
sed 's/apple/orange/' file.txt
#全局替换并忽略大小写(行内所有 "apple" 都变):
sed 's/apple/orange/gi' file.txt
#替换特定范围行(替换第 1 到 10 行):
sed '1,10s/apple/orange/g' file.txt
#直接修改文件
sed -i 's/old/new/g' file.txt
除了替换,sed 还能对行进行增删改查。
| 命令 | 含义 | 示例 | 说明 |
|---|---|---|---|
| d | Delete (删除) | sed '3d' file | 删除第 3 行 |
| sed '1,5d' file | 删除第 1-5 行 | ||
| sed '/error/d' file | 删除包含 "error" 的行 | ||
| a | Append (追加) | sed '3a\New Line' file | 在第 3 行后插入新行 |
| i | Insert (插入) | sed '3i\New Line' file | 在第 3 行前插入新行 |
| c | Change (替换整行) | sed '3c\New Line' file | 将第 3 行完全替换为新内容 |
| p | Print (打印) | sed -n '3p' file | 仅打印第 3 行(需配合 -n) |
#删除空行
sed '/^$/d' file.txt
#在匹配行后添加配置
# 在包含 "ServerName" 的行后添加 "ServerAdmin admin@example.com"
sed '/ServerName/a\ServerAdmin admin@example.com' httpd.conf
sed 支持基本正则表达式 (BRE)。若要使用扩展正则(如 +, ?, |),需加 -E 选项(或 \ 转义)。
# 删除以数字开头的行
sed '/^[0-9]/d' file.txt
# 删除空白字符开头的行
sed '/^[[:space:]]/d' file.txt
#将文件中的 "apple" 或 "banana" 都替换为 "fruit"。
sed -E 's/(apple|banana)/fruit/g' file.txt
3、awk 命令
awk 是 Linux/Unix 系统中最强大的文本处理和数据提取工具。
与 grep(搜索)和 sed(流编辑)不同,awk 是一门完整的编程语言。它擅长将文本视为结构化数据(如表格、CSV、日志),按列进行提取、计算、统计和格式化输出。
它的名字来源于三位创始人 Alfred Aho, Peter Weinberger, 和 Brian Kernighan 的首字母。
awk 的基本执行逻辑是:
逐行读取输入 -> 分割成字段(列) -> 匹配模式 -> 执行动作
基本语法
awk 'BEGIN{ 初始化 } /pattern/ { 动作 } END{ 结束处理 }' 文件名
- BEGIN块:在处理任何行之前执行一次(常用于打印表头、初始化变量)。
- 主循环:对每一行执行。如果行匹配 /pattern/,则执行 { 动作 }。如果没有模式,则对每一行执行。
- END块:在所有行处理完毕后执行一次(常用于打印统计结果、总和)。
内置变量
| 变量 | 含义 | 默认值/说明 |
|---|---|---|
| $0 | 整行内容 | 当前行的完整文本 |
| 1,1, 1,2...$N | 第 N 个字段 | 默认以空格或 Tab 分隔 |
| NF | Number of Fields | 当前行的字段总数(列数) |
| NR | Number of Records | 当前处理的行号(全局累加) |
| FNR | File Number of Records | 当前文件的行号(多文件时重置) |
| FS | Field Separator | 输入字段分隔符(默认空格/Tab) |
| OFS | Output Field Separator | 输出字段分隔符(默认空格) |
| RS | Record Separator | 输入记录分隔符(默认换行符 \n) |
实际使用举例
假设有一个文件 data.txt
Alice 25 Engineer
Bob 30 Manager
Charlie 35 Designer
#打印第 1 列和第 3 列(姓名和职位):
awk '{ print $1, $3 }' data.txt
输出:
Alice Engineer
Bob Manager
Charlie Designer
# 提取 /etc/passwd 中的用户名(第1列)和家目录(第6列)
awk -F: '{ print $1, $6 }' /etc/passwd
用awk提取adb devices的设备号
下面是adb devices输出类似如下内容
List of devices attached
192.168.1.100:5555 device
ABC123DEF456 device
emulator-5554 offline
adb devices | awk 'NR>1 && $2!=""{ print $1 }'
- NR>1:NR 是行号。NR>1 表示跳过第一行(即 "List of devices attached" 标题行)。
- $2!="":确保第二列(状态列)不为空,从而过滤掉末尾可能存在的空行。
- print $1:打印第一列,即设备序列号。
#只提取在线(device)状态的设备
adb devices | awk '$2=="device" { print $1 }'
#杀死任意指定名称的进程
#process_name 替换为你想要杀死的进程名(如 python, java, nginx)
ps -ef | awk '/[p]rocess_name/ {print $2}' | xargs kill -9
#杀死占用特定端口的进程
lsof -i :8080 | awk 'NR>1 {print $2}' | xargs kill -9

浙公网安备 33010602011771号