核心命令习题记录
1. 找出当前目录及其子目录下所有包含 “error” 关键词的日志文件,并输出文件名和包含 “error” 的行
- 使用场景 :在排查系统故障或软件问题时,需要快速定位到包含错误信息的日志文件及相关行,以便分析错误产生的原因。
- 命令 :
grep -r --include="*.log" "error" .-r:表示递归地查找当前目录及其子目录下的文件。--include="*.log":只查找后缀为.log 的日志文件,提高查找的针对性。- 输出结果示例 :如果在文件
subdir/app.log中有包含 “error” 的行,则输出类似subdir/app.log:2023/11/20 14:30:00 error occurred in module x的内容,即文件名和对应的包含 “error” 的行。
2. 打印出以 192.168.1.x 开头的行
a192.168.1.1 server1
192.168.1.2 server2
192.168.1.3 server3
-
使用场景 :在分析网络配置文件、服务器列表或网络流量日志等文件时,需要提取出特定网段的 IP 相关信息。
#me egrep -w "192.168.109.[0-9]" access.log -
命令 :
grep -w "^192\.168\.1\.[0-9]\+" filename-w:确保匹配的是完整的单词,避免匹配到类似 “192.168.1.10extra” 这样不符合要求的情况。^:表示行的开头。192\.168\.1\.:匹配 “192.168.1.”,其中\.是对 “.” 进行转义,因为 “.” 在正则表达式中表示任意字符。[0-9]\+:匹配一个或多个数字,即 IP 地址的最后一段。\+表示匹配前面的模式一次或多次
输出结果示例 :对于提供的示例数据,输出结果为:
192.168.1.2 server2
192.168.1.3 server3
3. 使用 awk 命令计算第二列的总和
root 10
user1 5
user2 8
-
使用场景 :在处理数据文件时,如统计用户使用资源总量、计算销售总额等场景,需要对某一列的数值进行求和运算。
-
命令 :
awk '{sum+=$2} END{print sum}' filename-
{sum+=$2}:对每一行来说,将第二列的值累加到变量 sum 中。 -
END{print sum}:在所有行处理完成后,打印出 sum 的值,即第二列的总和。
-
4. 找出访问次数超过 150 的 IP 地址
192.168.1.1 100
192.168.1.2 200
192.168.1.3 150
-
使用场景 :在分析网站访问日志时,需要找出高频访问的 IP 地址,可能是为了排查异常访问行为,如 DDoS 攻击等。
-
命令 :
awk '$2>150 {print $1}' filename
5. 使用 sed 命令将文件中的所有 “world” 替换为 “Linux”
Hello, world!
This is a test file.
Welcome to the world of Linux.
- 使用场景 :在修改配置文件、文档内容等时,需要批量替换某些字符串,如修改软件的名称、替换过时的术语等。
- 命令 :
sed 's/world/Linux/g' filename
6. 使用 sed 命令将配置文件中的 debug 设置为 false
port=8080
host=localhost
debug=true
-
使用场景 :在修改软件配置文件时,需要快速定位到某个参数并修改其值,如调整调试模式、开关某些功能等。
-
命令 :
sed -i 's/debug=true/debug=false/' filename-i:表示直接修改文件内容。
7. 找出所有包含 “ERROR” 的行,并且只显示日期和时间部分
[2023-01-01 00:00:00] INFO: System startup
[2023-01-01 00:01:00] ERROR: Disk full
[2023-01-01 00:02:00] INFO: User logged in
...
-
使用场景 :在分析日志文件时,只关心错误发生的时间,以便快速定位问题发生的大致时间段。
-
命令 :
grep "ERROR" filename | awk -F '[\[\]]' '{print $1}'-
grep "ERROR" filename:先筛选出包含 “ERROR” 的行。 -
awk -F '[\[\]]' '{print $2}':将行中的内容以 [ 和 ] 作为分隔符进行分割,并打印第二个字段,即日期和时间部分。 -
输出结果示例 :对于提供的示例数据,输出结果为:
-
2023-01-01 00:01:00 -
在 awk 中,-F 选项用于指定字段分隔符(Field Separator)。字段分隔符可以是一个字符,也可以是一个正则表达式。当使用正则表达式时,需要用方括号 [...] 来定义一个字符类。
-
8. 使用 sed 命令将文件中的所有注释行(以 # 开头的行)删除
# Configuration File
port=80
debug=true
logging=verbose
...
-
使用场景 :在处理配置文件、脚本等文件时,有时需要去除注释行,以便更清晰地查看有效代码或进一步处理文件内容,如统计代码行数等。
-
命令 :
sed '/^#/d' filename/^#/d:匹配以 # 开头的行,并将其删除。- 输出结果示例 :对提供的示例文件内容处理后,输出结果为:
port=80debug=truelogging=verbose
9. 使用 sed 命令将文件中的所有 IP 地址的最后一段数字替换为 X
127.0.0.1 localhost
192.168.1.1 server1
192.168.1.2 server2
...
-
使用场景 :在对网络数据进行脱敏处理时,需要隐藏 IP 地址的部分信息,以保护隐私或满足安全要求。
-
命令 :
sed -r 's/([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+/\1.X/g' ipx.txt-r:启用扩展正则表达式模式。([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+:匹配 IP 地址\1.X:用第一个括号中的匹配内容(即 IP 地址的前三段)加上 .X 来替换原来的整个 IP 地址。- 输出结果示例 :对提供的示例数据进行替换后,输出结果为:
127.0.0.X localhost192.168.1.X server1192.168.1.X server2
10. 找出 Nginx 所有返回状态码为 404 的请求
192.168.109.1 - - [23/May/2025:14:30:43 +0800] "GET /poweredby.png HTTP/1.1" 200 368 "http://192.168.109.3/a.txt" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0" "-"
192.168.109.1 - - [23/May/2025:14:31:02 +0800] "GET /h.html HTTP/1.1" 404 3650 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0" "-"
-
使用场景 :在分析网站访问日志时,需要找出所有不存在的页面请求,以便优化网站内容或修复链接错误等。
-
命令 :
awk '$9 == "404" {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr'- 输出结果为
/?a=3,即对不存在的页面的请求记录。
- 输出结果为
11. 使用 sed 在 <body> 标签内插入一个 <div> 块,并包含一些自定义的文本内容
<html>
<head>
<title>Sed Learn</title>
</head>
<body>
<p>Welcome to my page.</p>
</body>
</html>
-
使用场景 :在修改 HTML 文件时,需要在特定位置插入新的标签和内容,如添加广告代码、页面提示信息等。
-
命令 :
sed '/<body>/a <div>Custom text content</div>' filename-
/</body>/a <div>Custom text content</div>:在匹配到<body>标签的行之后添加指定的<div>标签及内容。 -
a\ # 在当前行下面插入文本。
-
输出结果示例 :对提供的示例 HTML 文件内容修改后,输出结果为:
-
12. 使用 sed 和正则表达式,提取每一行中的 IP 地址和请求方法(如 “GET” 或 “POST”),并输出它们
10.0.0.1 - - [01/Jan/2023:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1024
10.0.0.2 - - [01/Jan/2023:00:00:02 +0000] "POST /submit HTTP/1.1" 404 327
-
使用场景 :在分析网络日志时,需要提取出关键的访问信息,如访问者的 IP 地址和请求方式,以便进行流量分析、安全审计等工作。
-
法一:awk '{print $1,$6}' 12.txt | sed -r 's/\"//g' 法二:awk '{print $1, $6}' FS='[" ]+' 12.txt # 适用于复杂情况 -
命令 :
sed -r 's/^([0-9.]+).*"([A-Z]+) .*$/\1 \2/' 12.txt^([0-9.]+)匹配192.168.1.1(捕获组\1)。.\*"匹配- - [23/May/2025:12:34:56 +0800] "。([A-Z]+)匹配GET(捕获组\2)。.\*$匹配/index.html HTTP/1.1" 200 1234。- 输出结果示例 :
10.0.0.1 GET10.0.0.2 POST
13. 场景面试题
场景描述:假设你是一名系统管理员,负责维护公司的一个网站服务器。最近,你注意到服务器日志文件 webserver.log 中记录了大量的访问请求,你怀疑服务器可能遭受了分布式拒绝服务攻击(DDoS)。你需要分析日志文件,找出异常的访问模式,以便采取措施防止服务器资源被过度消耗。
日志文件示例 (webserver.log):
192.168.1.1 - - [01/Jan/2023:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1024
192.168.1.2 - - [01/Jan/2023:00:00:02 +0000] "POST /submit HTTP/1.1" 404 327
192.168.1.1 - - [01/Jan/2023:00:00:03 +0000] "GET /index.html HTTP/1.1" 200 1024
10.0.0.1 - - [01/Jan/2023:00:00:04 +0000] "GET /index.html HTTP/1.1" 200 1024
192.168.1.3 - - [01/Jan/2023:00:00:05 +0000] "GET /index.html HTTP/1.1" 200 1024
...
14. 面试问题
(1)如何使用 grep 或 awk 从 webserver.log 文件中提取出所有状态码为 404 的请求记录
-
使用场景 :在排查网站页面不存在问题、优化网站内容或分析访问错误情况时,需要找到所有返回 404 状态码的请求记录。
-
grep 命令 :
grep ' 404 ' webserver.log404:通过匹配前后有空格的 404 来精确找到状态码为 404 的行(因为日志中状态码通常前后有空格等分隔符)。- 输出结果示例 :对于提供的 webserver.log 示例数据,如果有如下内容:
192.168.1.2 - - [01/Jan/2023:00:00:02 +0000] "POST /non-existent.html HTTP/1.1" 404 327- 则这条记录会被提取出来。
-
awk 命令 :
awk '{for(i=1;i<=NF;i++){if($i=="404"){print $0}}}' webserver.logfor(i=1;i<=NF;i++):循环检查每一行的每个字段。if($i=="404"):判断当前字段是否等于 404。{print $0}:如果找到,则打印整行。- 输出结果示例 :同 grep 命令示例,输出状态码为 404 的请求记录。
(2)编写一个 awk 脚本来统计每个 IP 地址在日志文件中出现的次数,并输出出现次数最多的前 10 个 IP 地址及其次数
- 使用场景 :在分析网站流量、排查 DDoS 攻击等异常访问情况时,需要了解各个 IP 地址的访问频率,重点关注高频访问的 IP。
- awk 脚本 :
awk '{count[$1]++} END{for(ip in count){print ip, count[ip] | "sort -k2 -nr | head -n 10"}}' webserver.log{count[$1]++}:以 IP 地址(假设日志文件中每行的第一列是 IP 地址)为索引,每次遇到一个 IP 地址就将其对应的计数值加 1。END{for(ip in count){print ip, count[ip] | "sort -k2 -nr | head -n 10"}}:在处理完所有行后,遍历 count 数组,将 IP 地址及其出现次数打印出来,并通过管道传递给sort -k2 -nr | head -n 10命令进行排序和取前 10 名的操作。sort -k2 -nr表示按照第二列(出现次数)进行数值降序排序,head -n 10表示取前 10 行。- 输出结果示例 :假设 webserver.log 中有多个 IP 地址的访问记录,输出结果可能为:
192.168.1.1 5010.0.0.1 30192.168.1.2 25- ...(共 10 行,按出现次数从多到少排列)
(3)如何使用 sed 在日志文件中找到所有 GET 请求,并将其方法从 “GET” 更改为 “TRACE”
- 使用场景 :在进行网络调试、测试服务器对不同请求方法的处理情况或对访问数据进行特殊标记等操作时,需要修改日志文件中的请求方法。
- 命令 :
sed -i 's/GET/TRACE/' webserver.log-i:直接修改文件内容。s/GET/TRACE/:将每一行中的 “GET” 替换为 “TRACE”。- 输出结果示例 :对于原日志文件中的一行:
192.168.1.1 - - [01/Jan/2023:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1024- 修改后变为:
192.168.1.1 - - [01/Jan/2023:00:00:01 +0000] "TRACE /index.html HTTP/1.1" 200 1024
15. 编写一个命令或脚本,从文件 network.log 中提取出所有的有效 IP 地址(有效的 IP 地址是指每段数字都在 0 到 255 范围内的地址)
Jan 1 00:00:00 server1 notice: Connection from 192.168.1.10 to port 80
Jan 2 00:05:00 server1 warning: Unauthorized access attempt from 10.0.0.5
Jan 2 00:10:00 server2 info: User logged in from 172.16.0.3
Jan 3 00:15:00 server1 error: Service down, attempted restart from 192.168.1.1
Jan 3 00:20:00 server2 notice: Connection from 192.168.1.100 to port 443
Invalid IP: 999.999.999.999
Jan 4 00:25:00 server1 info: Maintenance performed by admin at 192.168.1.200
-
使用场景 :在处理网络日志、分析网络流量或处理网络相关数据时,需要准确提取出有效的 IP 地址,以进行进一步的网络分析、统计或安全审计等工作,同时排除掉无效的 IP 地址干扰。
-
脚本(extract_valid_ips.sh)
#!/bin/bash # 提取并验证有效 IP 地址 grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' network.log | while read -r ip; do # 将 IP 分割为四部分 IFS='.' read -r -a parts <<< "$ip" # 验证每部分是否在 0-255 范围内 valid=true for part in "${parts[@]}"; do # 检查是否为纯数字且无前导零(除非是单个 0) if ! [[ "$part" =~ ^[0-9]+$ ]]; then valid=false break fi # 检查是否有前导零(如 01、001 等) if [[ "$part" =~ ^0[0-9] ]]; then valid=false break fi # 检查数值范围 if (( part < 0 || part > 255 )); then valid=false break fi done # 输出有效 IP if [ "$valid" = true ]; then echo "$ip" echo -e "/n" echo "解析完毕!" fi done#解释 while read -r ip; 是一个在 Bash 脚本中常用的基本结构,用来逐行读取输入,并将每行的内容赋值给变量 ip read -r -a parts: read: 用于从标准输入读取一行数据,并将数据赋值给变量。 -r: 禁止反斜杠(\)作为转义字符。这意味着即使字符串中包含反斜杠,也不会被解释为转义字符。 -a: 将输入的单词赋值到数组中。在这种情况下,单词是由 IFS 定义的分隔符分割的部分。 parts: 是存储分割后的数据的数组变量名。 <<< "$ip": <<<: 是 Bash 中的 “Here String” 操作符,用于将字符串作为标准输入传递给 read 命令。 "$ip": 是一个变量,存储要被处理的字符串(在这个场景中是 IP 地址)。 [[ ... ]]: 双方括号用于条件测试。它比单方括号 [ ... ] 提供更严格的语法检查,支持更多的操作符,如正则表达式匹配。 变量名用双引号括起来是为了防止字符串中的空格或其他特殊字符导致解析错误。 在 =~ 中,~ 是一个特殊符号,与等号 = 一起构成正则表达式匹配操作符。具体来说,~ 的作用是表示右边的表达式是一个正则表达式。它告诉 Bash 解释器,右边的表达式应该按照正则表达式规则进行匹配,而不是普通的字符串比较。输出
[root@fangning 524shell]# ./extract_valid_ips.sh 192.168.1.10,'解析完毕' 10.0.0.5,'解析完毕' 172.16.0.3,'解析完毕' 192.168.1.1,'解析完毕' 192.168.1.100,'解析完毕' 192.168.1.200,'解析完毕'

浙公网安备 33010602011771号