多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Linux文件查看与编辑命令实战:cat/less/sed/awk选型逻辑

Linux文件查看与编辑命令实战:cat/less/sed/awk选型逻辑 cat一个几百MB的日志终端直接卡死光标闪了半天也没输出完——这是我带过的每个新人几乎都会踩的第一脚。等他们手忙脚乱CtrlC之后往往还会补一句查看文件内容不就这么几个命令吗能有多大区别。区别确实很大大到less和cat之间隔着一个会不会用Linux系统常用命令的分水岭。这篇是Linux系统常用命令系列的第二篇聚焦文件内容查看与编辑。我打算用最贴近实战的方式把cat、less、head、tail、grep、vim、sed、awk这几组命令掰开揉碎。它们覆盖了日常排查日志、阅读配置、批量改文件的九成场景也是面试题里反复出现的常客。无论你是刚转行过来的运维新人还是被领导临时抓去处理服务器问题的开发这篇都值得花二十分钟过一遍。读完你能建立起一套自己的选择逻辑什么场景该用什么命令为什么用它以及用到什么程度就该换工具。1. 文件查看的下限与上限cat、less、head、tail的选择逻辑很多人学Linux命令是背参数表学到后面发现真正困难的不是记不住命令而是拿到一个真实文件时不知道选哪个。所以这一章我先不罗列参数而是讲清楚这几个命令各自的适用边界。1.1cat只适合小文件要拼接两类场景cat的全称是concatenate本意是拼接文件。cat a.txt b.txt c.txt这种用法才是它的本职工作。在终端里直接cat一个文件只是它的附加功能却被很多人当成了唯一功能。如果你要看的文件只有几十行比如刚写完的配置文件、浅浅几行的服务状态文件那cat完全够了。加上-n参数还能显示行号配合grep定位问题很快cat -n /etc/nginx/nginx.conf | head -50但文件一旦超过几百行或者单行内容特别长cat的劣势就暴露了内容一次性糊到屏幕上头部直接滚出视野你只能靠鼠标往上翻。更糟糕的是如果你在SSH终端里误cat了一个二进制文件终端可能直接乱码甚至假死。在服务器上cat二进制文件导致SSH会话异常是运维事故里很低级但很常见的一种。提示:cat还有一个容易被忽略的细节——它默认不会在文件结尾缺换行符时自动补一个。所以用cat拼接多个文件时如果每个源文件末尾都没有换行拼出来就会变成一整行。手动补换行通常是写脚本时的必修课。1.2less是长文件阅读的正解不是vim的平替less这个名字来源于less is more——它是早期more命令的增强版。more只能往后翻less可以前后翻还能搜索、跳转这基本覆盖了阅读长文件的全部需求。打开一个几万行的大日志less app.log进入less之后按j或向下方向键逐行往下按k或向上方向键往回看。按空格或Ctrlf翻下一页按Ctrlb翻上一页。输入/关键词向下搜索按n跳转到下一个匹配项按N跳到上一个。输入G跳到文件末尾输入gg回到开头。输入行号G直接跳到指定行比如100G就是去第100行。按q退出。我排查线上问题时less用得最多的场景是先grep定位行号然后less打开文件指定跳到那一段上下文。比如grep -n error app.log拿到行号是5321那我直接less 5321 app.log就能精确定位到那一行不要从头一页页翻。less还有一个独特优势打开大文件时它并不会把整个文件读进内存而是按需读取所以哪怕文件有几个GB打开速度依然很快。这一点vim都做不到——vim打开大文件会明显卡顿而less稳得很。1.3head、tail负责只看一头一尾head和tail的定位很明确你只关心文件的开头几行或末尾几行没必要打开整个文件。查看一个服务最近有没有启动成功最常用的就是tailtail -50 app.logtail -f是日志跟踪的利器。-f会持续等待文件新增内容并直接打印放着不管就能实时看到日志滚动tail -f app.log如果还想过滤一下配合grep即可tail -f app.log | grep ERROR这里有个经验点tail -f配合grep时如果日志量特别大可能追不上输出速度导致漏数据。更好的做法是先用tail落一个快照文件再分析或者直接用grep读文件而不是实时追流。生产环境要慎用tail -f挂在前台占着终端不说日志疯狂刷新时还会吃掉不少CPU和IO。head的用法就简单了默认看前10行加上-n自定义行数head -20 /etc/nginx/nginx.conf1.4 取中间某一段区间用sed比用编辑器快得多想取文件第100行到第200行最直接的方式是sed -n 100,200p file。这个放在后面跟sed一起细讲但这里先说明不要打开编辑器再翻过去在终端里一条命令出结果效率和体验完全是两个量级。查看类命令还有个隐藏技巧把多个命令串进管道比如只看文件第50行到第70行并且去掉空行。这种组合在排查配置时特别常用。2. 查找与统计grep配合wc -l、sort、uniq解决九成需求文件查看了接下来问题就来了怎么从几万行日志里找到跟报错相关的那几行如果这个动作你还靠肉眼滚动那效率基本为零。grep就是干这个的它是Linux系统常用命令里被使用频率最高的命令之一我觉得没有之一。2.1grep最常用的参数按实用度排序grep的参数很多但日常高频使用的不超过10个。先不急着一口气全学先把这几个记熟grep 关键词 文件 grep -i 关键词 文件 # 忽略大小写 grep -n 关键词 文件 # 显示行号 grep -v 关键词 文件 # 反向匹配排除含关键词的行 grep -r 关键词 目录 # 递归搜索目录下所有文件 grep -E A|B 文件 # 扩展正则匹配A或B grep -l 关键词 目录/* # 只列出含关键词的文件名-n这个参数我建议养成条件反射只要grep就加。因为拿到行号之后你才能用sed或者less 行号去定位上下文。没有行号的grep结果就像房产中介只告诉你小区很好却不给你门牌号参考价值大打折扣。-v也是一个日常兜底神器。比如查看日志时想过滤掉那些心跳之类的骚扰信息grep -v heartbeat app.log | tail -202.2 统计出现次数grep -c与管道结合最简单的统计是grep -c直接数匹配行数grep -c ERROR app.log但要统计有哪些不同的错误类型各自出现多少次grep -c就不够用了。这时候要用到三个命令的组合grep -oE \[[A-Z]\] app.log | sort | uniq -c | sort -rn这条命令的含义是把日志里所有用中括号包起来的大写字母标签比如[ERROR]、[WARN]全部抽出来排序后去重统计次数再按数字从大到小排序。这样一眼就能看出当天日志里哪种类型最多。uniq有个重要前提它只能去掉相邻的重复行。所以必须先sort再uniq否则计数会错乱。这个坑我见过不少新人踩单独uniq -c发现同样的词出现了好几行百思不得其解其实就是这个原因。2.3 多文件搜索与二进制文件干扰在多个文件里找内容grep -r能递归处理目录但它会把二进制文件也扫一遍输出一堆乱码甚至还会报binary file matches。处理办法是加-I让grep跳过二进制文件或者加--include限定只搜索某种后缀grep -rnI TimeoutException /opt/app/logs --include*.log这里-I特指忽略二进制文件跟-i忽略大小写仅差一个字母的大小写容易混淆我建议你实操一次把这两个参数都记住。另一个多文件搜索的实用技巧想找出哪几个配置文件里出现过某个关键词就用-lgrep -l listen 443 /etc/nginx/conf.d/*结果直接列出命中文件的名单配合后续的vim逐一修改很顺手。2.4find查找文件名grep查找文件内容很多初学者分不清find和grep的区别find是按文件名、文件大小、修改时间等元信息找文件grep是按内容找。两者配合使用的场景很典型——在/data/logs目录下找到三天内修改过、且内容含有OutOfMemory的.log文件find /data/logs -name *.log -mtime -3 | xargs grep -l OutOfMemoryxargs在这里发挥的作用是把find输出的一串文件路径逐个或分批传给grep作为参数。这种串联模式在Linux系统常用命令里非常常见文件查找和内容查找的任务往往是分不开的。3. vim的三模式切换新手最常卡住的点如果你经历过在vim里怎么按都输不进去字、乱按键盘后文件内容突然变奇怪的阶段那你已经踩过了几乎所有Linux新人都踩过的坑。vim的学习曲线是陡的但它确实是Linux系统里绕不开的编辑工具。3.1 先把三种模式刻进脑子vim有且仅有三种模式命令模式启动vim默认所在模式此时按键被视为命令比如dd删一行、yy复制一行、p粘贴。在这个模式下输入文字只会被当成命令执行不会写进文件。插入模式按i进入左下角会显示INSERT标识此时所有输入都会写入文件。想退出插入模式按Esc。末行模式也叫底行模式按:进入在屏幕底部输入命令比如:wq保存退出、:q!不保存退出、:%s/old/new/g全局替换。新手最常卡住的场景是不知道自己正处在哪个模式里。判定方法很简单——看左下角是否显示INSERT有就是插入模式按过一次Esc之后通常回到命令模式。3.2 从打开文件到保存退出一条最稳妥的路径我推荐新手先建立最小可用操作集别一上来就背快捷键而是把这几个高频操作做成肌肉记忆vim 文件名打开后按/关键词搜索定位按n跳转下一个。把光标移到要改的位置按i进入插入模式。修改完成后按Esc回到命令模式。按Shift;进入末行模式输入wq回车保存退出。万一改乱了想放弃修改直接退出就输入:q!感叹号表示不保存强制退出。这个命令在面试题里几乎是必问的如何不保存退出vim答案就是q!。3.3 高频操作速查dd、yy、p这三个是我日常用得最多的dd剪切当前行到缓存yy复制当前行p把缓存内容粘贴到当前行下方。组合用法比如想把这行调整到下一行直接dd到缓存再移动光标到合适位置p。多文件编辑时:bn切换到下一个文件、:bp切回上一个文件。文件多到不想记顺序的时候:ls可以列出所有已打开的文件然后:b 数字直接跳过去。提示:如果你用的是笔记本键盘Esc键位置很远很别扭可以在vim里配置把Ctrl[当作Esc用或者把J、K之类的键映射成Esc。这里不展开具体映射方法但很多工程师都会在~/.vimrc里做这类优化。3.4 大文件编辑的替代思路vim打开100MB以上的文件会变得很慢因为要构建语法高亮、撤销记录等结构。碰到这种情况我的习惯是先less快速浏览确定要改哪几处之后再针对性地用sed原地修改或者用vim的行号直接跳过去改特定行而不是一整个大文件平铺打开vim 行号 大文件.log这个思路在运维日常里非常实用也是Linux系统常用命令从会用到用得聪明的一个分水岭。4. sed与awk两条命令打通批量编辑和字段提取如果说vim是手术刀精细但一次只能处理一个点那sed就是收割机适合对大量文本做批量规整。awk则更像一个微型编程语言专门干按字段提取、汇总统计的活。4.1sed的原地修改与正则替换sed最核心的用法之一是替换。命令格式是sed s/旧内容/新内容/标志 文件标志位最常用g代表全局替换不写g的话一行内只替换第一个匹配。把文件里所有localhost换成127.0.0.1sed -i s/localhost/127.0.0.1/g app.conf-i是原地修改直接在原文件上生效不加的话只会把替换后的结果打印到终端原文件纹丝不动。刚学时我总忘加-i改完发现文件没变一度以为自己弄坏了什么。在真正执行带-i的替换之前务必先用不带-i的命令跑一遍肉眼确认替换结果合理sed s/192.168.1.1/192.168.2.1/g app.conf确认无问题之后再加上-i执行。生产环境如果连续误操作可能直接让一个服务起不来这个检查习惯真的能救命。sed的删除也很常用。比如删除所有空白行sed /^$/d file或者想删除从第5行到第10行的内容sed 5,10d file4.2awk处理字段提取面试和实战双高频awk的默认单位是行每行又被空格或制表符切成多个字段$1是第一个字段$2是第二个$0是整行。它的结构是awk {模式; 动作}动作里可以写print等操作。看一个经典场景——ps命令输出的进程列表我想提取第二列的PID和最后一列的命令路径ps aux | awk {print $2, $11}遇到分隔符不是空格的文件比如/etc/passwd里用冒号分隔可以用-F指定分隔符awk -F: {print $1, $7} /etc/passwd这条命令打印的是用户名和登录shell。awk还有内置变量和条件判断的能力。比如查看某日志里状态码是500的行的行数和行号awk $9 500 {print NR, $0} access.log这里的$9是假设第9列是状态码NR是当前行号会打印出所有状态码为500的完整行和对应行号。条件里还可以用、、、!这些比较运算符基本上把它当一个小型查询语言用。4.3sed适合作全局修改awk适合按列提取二者各自的地盘很多人会纠结一个问题一个任务到底用sed还是awk我的判断标准很简单如果操作的对象是行内的字符串内容比如替换、删除匹配行、在指定行后插入内容选sed如果操作对象是把一行拆成几列来筛选或汇总选awk。两者经常配合使用——先用sed把无关内容排除再用awk提取关键字段。举一个综合例子清理日志里所有时间戳前缀然后按IP统计访问次数。sed s/^\[[0-9-]* [0-9:]*\]// access.log | awk {print $1} | sort | uniq -c | sort -rn一条管道干完四件事这就是Linux命令行的魅力。5. 大日志排查的综合实战一次把命令全部串起来讲了这么多命令如果还停留在单个命令单独用的层面那效率和没有系统性差不多。真实线上场景往往是多命令协作这一章我用一个完整的例子把所有内容串一遍。5.1 场景Nginx访问日志里找出访问量最高的IP以及它的最近请求假设有一个access.logRoughly长这个样子192.168.1.10 - - [21/Mar/2025:10:00:01 0800] GET /api/user HTTP/1.1 200 523 192.168.1.11 - - [21/Mar/2025:10:00:03 0800] GET /api/order HTTP/1.1 500 0 192.168.1.10 - - [21/Mar/2025:10:00:09 0800] POST /api/login HTTP/1.1 200 321第一步统计前3个访问量最高的IP。awk {print $1} access.log | sort | uniq -c | sort -rn | head -3awk把第一列IP提取出来sort排序后uniq -c统计次数再sort -rn按次数从高到低排最后head -3取前三。第二步找出这个IP最近发出了哪些请求。grep 192.168.1.10 access.log | tail -20于是我们看到的信息从几十万行不知道哪行重要变成了目标地址精准打击整个过程在秒级内完成。5.2 场景定位报错时间点附近的上下文有的日志错误是持续性的一条条看浪费时间。更好的思路是先用grep -n拿到第一个错误出现的行号再用sed取它的前后各20行看上下文。grep -n ERROR app.log | head -1 # 假设输出 2321: 2025-03-21 10:00:01 ERROR xxx sed -n 2301,2341p app.log这两条命令组合相当于把事故现场前后40行完整“拉”出来。如果错误不止一个还可以把所有ERROR出现位置的行号收集起来循环读取上下文不过这是脚本级的操作了这里不展开。5.3 生产环境里的三条操作禁忌第一绝对不要在不确定的情况下对生产配置文件执行带-i的sed命令尤其是改正则替换时一个不小心就把整文件内容改得面目全非。执行前先备份或者先在不带-i的模式下预览输出。第二不要用cat直接查看大文件原因前面已经说过了。如果非要用至少先ls -lh看一眼文件大小。第三不要在一次命令里堆太多管道。命令写得太长确实看起来很厉害但一旦某一步输出格式变化这条命令就完全不可读了。如果真的需要复杂处理我更建议存成脚本而不是在命令行里写上百个字符的一行流。脚本还能重复使用这个习惯长期来看非常值钱。6. 面试爱问的几个细节题顺便检验你对命令的理解热搜词里出现了linux面试题测试linux命令大全手册linux常用命令大全运维这些关键词说明有不少人是为了备战面试找资料。我在带新人和做技术面试时常会挑几个细节问题来快速判断对方是不是真的用过、想过这些命令而不只是看了一堆列表。面试官常问的包括cat和less的区别是什么tail -f和tail -F的区别是什么grep -E和grep的不同在哪vim里怎么替换所有匹配的字符串sed -i如果写错了怎么恢复其中tail -F这个点值得展开一点。-F会追踪文件描述符的变化即使日志文件被轮转重命名了tail -F也能重新跟随新的文件而tail -f只跟随原文件描述符。在日常日志切割场景下tail -F更适合长期跟踪。很多人在面试时能说出-f但说不清-F这恰好是考察有没有真正在日志轮转环境里调过手段的经历。vim全局替换的命令是:%s/旧/新/g%表示所有行g表示一行内所有匹配项。如果只想替换部分行可以把%换成行号范围比如:5,20s/旧/新/g。grep家族里面还有grep -A、grep -B和grep -C三个参数-A显示匹配行之后的N行-B显示之前N行-C显示前后各N行。这个在看异常堆栈时特别有用grep -C 5 NullPointerException app.log一次把异常抛出点前后的上下文都带出来。这些细节并不难但它们能体现你对命令的理解程度远不是背几个参数能比的。我觉得准备面试时与其刷题不如找一台机器把日志翻来覆去地查几遍这些细节自然就进脑子了。7. 把常用命令沉淀成自己的命令手册写到这里最后一个建议是不要把Linux系统常用命令当成一次性学习而是要建立自己的快速查阅系统。方法有两种一种是把自己常用的命令积累到一个笔记文件里遇到就补另一种是在本地建一个命令速查脚本比如写一个cheat.sh之类的自用工具。我个人倾向于第一种。日常工作时多留心记录比如处理完一次故障后把当时用过的命令链整理到自己的笔记里标注清楚每一步干什么。三个月后回看这些都是比任何命令大全都实用的一手材料。还有个小技巧用history命令查看自己最近用过的命令记录里面往往会沉淀出那些不用思考就能敲出来的高频命令。有意识地把这些命令里不熟悉的部分补一补学习效率比啃整本手册高很多。
返回列表