ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux文件查看命令全解析:从cat到awk的选型指南

Linux文件查看命令全解析:从cat到awk的选型指南 在Linux服务器上排查线上问题时最常做的动作是什么我猜八成是打开日志文件看一眼。而“看文件”这个动作看起来简单实际上细究起来门道不少是看全部还是看尾部要不要带行号几十万行的日志用cat直接糊一脸终端立刻卡成幻灯片二进制文件直接cat屏幕全是乱码越看越懵。这篇文章我把Linux里跟文件查看相关的命令做一次系统对比从最基础的cat、tac到分页浏览的more、less再到能顺手干活的grep、sed、awk最后还有面向二进制的od、hexdump一次性讲清楚它们各自适合什么场景、怎么用以及我实际踩过哪些坑。不管你是在做运维排查、写脚本处理日志还是正好在准备面试这篇内容都能让你把文件查看这件事用得明明白白。1. 文件查看命令全景与选型思路1.1 为什么文件查看命令值得单独花心思整理很多初学者接触Linux的第一条命令就是cat会用cat之后似乎“查看文件”这个需求就已经满足了。但真正进了生产环境会发现cat能应付的场景非常有限看一个几GB的业务日志cat一进去终端直接卡死刷出来的内容还没法往回翻想找昨天下午某条报错前后的上下文cat翻半天眼睛都花遇到一个没有扩展名的配置文件cat打开全是乱码根本不知道是什么格式。这些情况每天都在发生而解决办法往往只是一个更合适的命令。文件查看是Linux运维、开发、排障中频率最高的操作之一没有系统地梳理过这些命令遇到问题时东试一个西试一个效率非常低。我自己带过一些新人发现只要把查看命令这条线理清楚他们排查问题的速度立刻上了一个台阶因为“看文件”是整个定位链条的第一步这一步慢了后面全慢。所以这篇文章名义上是在讲命令对比本质上是在讲一套按场景选工具的思路。你不需要背下所有参数只要记住什么场景该用哪类命令具体用法随时可以查手册。1.2 三个问题快速确定该用哪个命令面对一个文件我先问自己三个问题答案基本能把命令圈定在一个很小的范围内。第一个问题这个文件是文本还是二进制文本文件直接用cat、less、head这些命令都很安全二进制文件或者不确定格式的文件先别急着cat用file看一下类型再用od、hexdump这类工具去看底层字节不然看到的就是一屏乱码和一句“这文件是不是坏了”的疑问。第二个问题文件有多大几百KB的小文件用什么命令都无所谓cat最直接几十MB甚至上GB的大文件cat就不合适了less、tail、sed切片才是正路因为它们是按需读取不会一次性把整个文件塞进终端。第三个问题我只是想看还是要边看边筛选、统计、加工纯浏览用less最舒服要按关键词捞信息grep是首选要按行号或者模式切一段出来sed很顺手要做列级统计、格式转换awk是正牌工具。这三个问题问完命令基本就定了。我把这个选型思路整理成一个速查表平时拿不准的时候扫一眼就能定下来判断条件推荐命令为什么这么选小文本文件完整浏览cat / nl简单直接附带行号大文本文件分页阅读less按需加载不卡终端只关心文件头部/尾部head / tail精准取片段开销最小实时跟踪日志新增内容tail -F自动重试打开日志切割不失效找关键内容并看上下文grep -n -C定位到行并显示前后文截取指定行号区间sed -n a,bp轻量切片不打开整个文件按列拆分、统计汇总awk结构化文本的字段级处理二进制文件、编码查看od / hexdump -C以字节为单位看真实内容两个文件做对比diff / cmp文本比差异二进制比字节这张表是我在实际工作中反复用到的里面每一项都对应着一类高频场景后面几节我会逐个展开讲用法和细节。2. 基础查看命令详解cat、more、less、head、tail2.1 cat与tac连续查看整份文件的利与弊cat是Linux里最基础的文件查看命令全称concatenate它的本职工作其实是连接多个文件并输出但因为最简单的用法就是跟一个文件名所以被当成了“看文件”的默认工具。cat直接输出文件全部内容常用参数也就这么几个-n给每一行加行号-A显示不可见字符-s压缩连续空行。比方说想给配置文件标号可以直接cat -n /etc/nginx/nginx.conf这个命令在文件很小的时候非常好用尤其适合快速确认配置内容。但有两个明显的短板。第一大文件直接cat会瞬间把成千上万行刷到终端上你根本来不及看前面的内容早就滚出屏幕了终端还会因为大量渲染而卡顿。第二cat对二进制文件完全不友好遇到非文本内容就是一屏乱码而且它不会帮你判断这个文件到底是不是文本。tac是cat的反向输出命令名字就是把cat倒过来写功能也确实是“倒着打印文件”。它在某些场景下很实用比如日志文件是按时间顺序写的最新内容在末尾你想先看最后发生了什么直接tac app.log | head -n 50就能拿到最后的50行。不过tac同样适合小文件而且它输出的是整个文件的反向内容如果文件很大依然存在和cat一样的性能问题。我的建议是这俩只用来对付小文件大文件交给less和tail。2.2 more与less分页浏览的效率拐点当你第一次在一个几百MB的日志文件面前按下回车发现终端刷了半天还没停下来时就该认识less了。less的前辈是moremore是早期Unix时代的翻页工具支持空格向下翻页、b向上翻页、/搜索关键字但是方向键和PageUp这些现代交互它支持得很差看长文件体验很一般。less可以说是more的全面升级版名字来源也很幽默就是“less is more”。less最核心的价值是它不会一次性把整个文件读入内存而是按需加载当前屏幕显示的内容所以打开大文件非常快滚动也很流畅。它的交互按键非常值得记住按键功能空格 / f向下翻一屏b向上翻一屏G跳到文件末尾g跳到文件开头/关键字向下搜索?关键字向上搜索n / N下一个/上一个匹配项-N切换显示行号q退出less我日常的一个习惯是先用less打开文件按-N开启行号搜索关键词定位到目标行记下行号之后按q退出再用sed去精确切片。比如在less里搜到“ERROR”出现在第12345行那就可以用sed -n 12345,12360p app.log把这附近的上下文精确取出来整个过程干净利落不会污染屏幕。2.3 head与tail精准取头尾日志追踪神器head和tail是两个方向正好相反的命令head取文件开头tail取文件结尾默认都是10行。加-n可以指定行数比如head -n 50 file、tail -n 100 file。这两个命令的精髓在于“只取一部分”在文件极大的场景下它们几乎是零成本操作因为只需要读文件头或者尾部的少量数据。tail最重要的参数是-f它的意思是“follow”持续跟踪文件尾部的新增内容。启动之后终端会一直停在那里文件里每有新的一行写入它会立刻打印出来。这是排查在线服务问题时最常用的命令没有之一tail -f /var/log/nginx/access.log这里要注意一个坑tail -f跟踪的是打开时的文件描述符如果日志执行了切割比如logrotate把文件改名、新建了一个同名文件tail -f还会盯着那个已经被改名、不再写入的旧文件新内容不会显示。解决办法是用大写-F也就是tail -F它会检测到文件被重建并自动重新打开这在日志切割场景下非常可靠我后面在问题排查部分还会细说。2.4 实战组合日志排查的经典姿势单独的命令讲完把它们组合起来才是真正的日常操作。我举一个非常典型的场景线上服务报了告警我要从app.log里找出最近一次“数据库连接超时”前后的完整请求记录。第一步先用tail看最近一段时间的日志走向tail -n 200 app.log这样能快速判断故障是刚发生还是已经持续了很久。如果日志一直刷想看实时动态tail -F app.log | grep -E ERROR|Exception --color这样屏幕上只会显示包含ERROR或者Exception的行其他噪音被过滤掉。得到目标行号之后比如在12345行用sed切出上下文sed -n 12340,12360p app.log这一套组合拳看下来故障现场基本就还原了。整个过程没有动过日志文件本身也没有打开过完整的大文件终端不会被刷屏定位速度非常快。基础命令看似简单真正有价值的用法是“组合”这个思路从入门到进阶都适用。3. 高级文本处理工具grep、sed、awk的深度对比3.1 grep按内容抽丝剥茧的行定位神器grep是Linux里最常用的文本搜索命令核心逻辑是对输入的每一行做匹配命中的行输出到标准输出。它处理的单位是“行”所以特别适合用来从日志里捞信息。基础用法是grep 关键字 文件比如grep timeout app.log。但实际工作中我几乎不会只用这么朴素的用法通常会配合几个高频参数参数作用示例-n输出匹配行及其行号grep -n ERROR app.log-i忽略大小写grep -i error app.log-v反向匹配输出不包含关键字的行grep -v DEBUG app.log-A/-B/-C显示匹配行的后/前/上下N行grep -A 5 timeout app.log-E使用扩展正则表达式grep -E ERROR--color关键词高亮显示grep --color ERROR app.log比如我想知道一条异常SQL出现在哪里就可以用grep -n -A 10 select.*from.*users app.log这样既能定位到行号又能看到这条SQL后面10行的报错细节排错效率相当高。grep还有个好处是可以直接在管道里用command | grep xxx是Linux命令行的经典组合比如查进程、查端口、查输出内容处处都能用到。grep的性能在小到中等文件上表现很好但如果文件特别大建议先head或者tail缩小范围再丢给grep跑或者配合--line-buffered参数用于实时流式过滤。我实测过在几GB的日志上直接grep并不会立刻挂掉但等待时间确实很可观先用小命令缩小范围永远是好习惯。3.2 sed按行号与模式切片查看sed经常被叫做“流编辑器”很多教程会把它定义成一个文本编辑工具但在文件查看这个场景里它还有一个极其实用的身份按行号切片的查看器。它的核心语法是地址命令地址可以是行号也可以是正则表达式。最经典的一条切片命令是sed -n 100,200p app.log这行的意思是“只打印第100行到第200行”-n参数表示关闭自动打印p是打印命令。对比cat来说这个命令只读取和输出指定区间的内容大文件下完全不会卡顿非常轻量。模式匹配也能做地址比如想打印从第一个“ERROR”出现的那一行开始往后10行sed -n /ERROR/,10p app.log这个命令在找不到任何上下文线索时特别有用直接按模式“吸附”出一段区域。另外sed作为流编辑器还能做替换查看比如只想看日志里去掉时间戳后的内容sed s/^\[2024-[0-9-]* [0-9:]*\] // app.log虽然严格来说这已经不是“纯查看”了但日常处理日志格式时非常常用。我提一个关键细节sed结合管道非常顺手head -n 1000 app.log | sed -n 1,5p这类组合能灵活切割任意片段。如果你只想看文件的一部分内容又不想动原文件sed是我最推荐的一条命令。3.3 awk列级加工与统计分析awk和sed的思路完全不同它是按“列”字段来处理文本的。默认情况下awk以空格或制表符作为字段分隔符每一行的内容会被拆成$1、$2、$3……这样的字段$0代表整行。它的定位更像一个微型编程语言擅长做格式化输出、条件判断和统计计算。最基本的用法是按列提取内容。比如nginx的access.log每一行是“IP 时间 请求 状态码 响应大小”的结构我想只看IP和状态码awk {print $1, $9} access.log | head -n 10如果不希望按空格切而是按逗号或者其他字符切用-F指定分隔符awk -F, {print $2, $3} data.csvawk还能做统计。比如统计当天日志中各状态码出现的次数这是运维里很常见的需求awk {count[$9]} END {for (code in count) print code, count[code]} access.log这一句把“按状态码分组”和“计数”两个逻辑都完成了如果用grep一个个数要数到天亮。awk还能做数值统计比如计算某个列的总和、平均值awk {sum $10} END {print 总响应大小:, sum} access.logawk在处理带有固定格式的日志时性价比极高它不适合做模糊的全文搜索那是grep的活但一旦你摸清了字段结构awk能帮你快速完成很多平时需要写脚本才能做的事。3.4 三剑客联合实战一次日志分析的完整流程grep、sed、awk这三条命令经常被合称为“文本处理三剑客”它们各自的定位不同但在实际场景中往往是串起来用的。我举一个完整的例子从access.log里找出“今天10点到11点之间哪些IP请求最频繁Top 10是谁”。第一步用grep把时间段内符合条件的行捞出来假设时间字段在日志第4列格式是“10/Dec/2025:10:00:00”那就过滤出这个时间段grep -E 10/Dec/2025:10:|10/Dec/2025:11: access.log time.txt第二步用awk取出IP字段通常是第1列awk {print $1} time.txt ips.txt第三步用sort加uniq做计数排序这是Linux里统计Top N的标准套路sort ips.txt | uniq -c | sort -rn | head -n 10上面的输出会直接列出频率最高的10个IP以及它们各自的请求数量。整个过程没有写任何脚本只靠三条命令和管道几十秒钟就能得到结果。这就是我反复强调的“组合”的力量grep负责筛选行awk负责拆分列sort和uniq负责统计排序每一环都只做自己最擅长的事。如果还想进一步可以用sed把结果切片看看具体某几行请求长什么样或者用awk把某个IP的所有记录单独生成一个新文件。三剑客并不神秘它们就是把“观察文件”这件事从“看”升级成了“查、切、算”掌握之后排查和分析的效率完全是两个层次。4. 特殊场景与进阶工具nl、od、hexdump、diff4.1 nl让行号更规范很多场景下我们需要给文件加行号来查看cat -n是最常见的做法但如果你对行号的格式有要求nl是更专业的工具。nl默认只给非空行编号加-ba参数之后才会给所有行编号即使空行也算一行nl -ba app.log | head -n 20nl还支持自定义编号格式比如固定宽度、用零补齐nl -ba -w 5 -n rz app.log上面的-w 5表示编号占5个字符宽-n rz表示右对齐且用0补位。这在脚本里生成带行号的报表时很实用格式整齐美观。不过说句实话日常查看文件时cat -n和less -N已经够用了nl的价值更多体现在批量处理和脚本输出场景中。如果只是想在终端里快速看行号不用刻意切换记住一个就好我自己的习惯是less配合-N键切换因为不需要重新把文件读一遍。4.2 od与hexdump二进制文件的底层视角有一天你打开一个文件屏幕全是乱码第一个念头可能是“这文件坏了”。其实文件大概率没坏只是它是二进制格式或者编码跟终端预期的不一样。这时候就要请出od和hexdump这两个“底层视角”工具了。od全称octal dump默认用八进制展示文件内容。实际工作中我更常用od -c它按字符来解释每个字节od -c somefile如果努力分辨字符串内容这种输出方式比纯十六进制直观。更常用的是以十六进制加ASCII对照的方式输出这是查看二进制文件的黄金格式od -A x -t x1z somefile-A x表示地址用十六进制显示-t x1z表示每一字节转成十六进制并在行尾附上可打印字符的ASCII解释。hexdump的-C参数也能输出类似格式而且排版更贴近常见工具是我自己最常用的一条hexdump -C somefile以ELF可执行文件为例开头的字节永远是7f 45 4c 46也就是ASCII码里的“.ELF”。看到这个开头就能立刻确定这是一个Linux可执行文件。用od或者hexdump查看文件头、确认文件类型、判断编码、排查隐藏的不可见字符这些场景都是它们的主场。如果你在文件里看到的全是常见字符串只是偶尔夹杂几个“\0”之类的字符那它大概率是一个有固定结构的二进制数据文件直接用文本工具处理反而会失真。4.3 diff与cmp差异对比查看“查看文件”有时候不止看一个还要看两个文件到底哪里不一样。diff是文本对比的经典命令默认输出两个文件之间的差异行。更常用的是diff -u输出统一格式会包含上下文方便理解变更位置diff -u nginx.conf.old nginx.conf.new输出里会标明哪些行被删了前面带-、哪些行是新增的前面带以及上下文内容。这个命令不仅仅是“查看”它几乎是所有版本控制工具的内部基础逻辑。如果要对比的是二进制文件比如两个编译产物diff会变成“一坨乱码”模式这时应该用cmp命令。cmp逐字节比较两个文件输出第一个差异的位置和字节内容cmp file1.bin file2.bin它不像diff那样把整个差异打出来而是直接告诉你“从哪个字节开始不一样”对判断文件是否一致非常准确。另外还有一个comm命令它对两个排序后的文件做集合运算能分别列出“只在文件A中出现的行”“只在文件B中出现的行”“两文件共有的行”在比对配置项、白名单列表时也很顺手但要求输入文件先排序使用门槛比diff高一点这里就不展开细讲了。4.4 更多值得收藏的命令与技巧除了上面这些核心命令还有几个小工具在实际工作中出场率也很高值得一并收集起来。sort用来排序但它往往不是单独出现而是作为统计管道的一环。uniq -c会统计连续重复的行数但有个前提必须先排序才能让相同行聚到一起这就是为什么统计Top N的标准写法是sort | uniq -c | sort -rn。wc -l是统计行数最直接的方式看一个文件有多少行用wc -l file在评估日志体量时非常有用。配合前面讲的head、sed可以先看行数再决定用哪种方式取内容。watch命令用来周期性地重新执行某条命令并全屏刷新输出比如watch -n 2 wc -l app.log可以每两秒统计一次日志行数观察增长速度。它本身不算查看文件内容的命令但用它监控“文件变化趋势”非常直观。如果你经常用管道把命令行输出传给less来分页但又想保留颜色直接用less -R就能避免转义字符变成一堆乱码grep --color ERROR app.log | less -R这个组合很适合在需要“搜索分页”同时进行的场景颜色保留下来之后扫视关键内容的速度会快很多。5. 常见问题与排查技巧实录5.1 大文件卡顿与内存问题怎么破我自己第一次在生产环境用cat看一个2GB的日志时终端先是疯狂滚动然后直接卡住按CtrlC都没反应最后只能关掉SSH窗口重连场面非常狼狈。事后想想完全是命令选型的问题。cat这类命令会把整个文件内容一股脑输出到终端终端要渲染成千上万行文本CPU和内存开销瞬间拉满。大文件场景下推荐的做法有三类如果想从头浏览用less它只加载当前屏幕需要的内容如果只想看某一段用head、tail、sed切片只读一小部分数据如果必须拿到完整内容做进一步处理那就重定向到文件让输出落到磁盘而不是终端sed -n 1,10000p big.log segment.log核心原则就一条别把大文件整个倒进终端让文件内容和屏幕显示之间永远隔着一层“切片”或者“翻页”的缓冲。5.2 中文乱码与编码识别Linux下打开一个文件全是乱码十有八九是编码问题。最常见的情况是文件本身是GBK或GB18030编码但终端默认用UTF-8解析。判断编码最直接的工具是file命令file -i somefile.log它会输出文件的字符集信息比如charsetutf-8或者charsetiso-8859-1。确认编码之后用iconv做转换就能正常查看iconv -f GBK -t UTF-8 somefile.log somefile_utf8.log转换后再用less打开乱码基本就消失了。还有一个实用的习惯如果经常要处理Windows传过来的文件它们默认很可能是GBK可以在.bashrc里定义一个快捷函数比如alias gbkiconv -f GBK -t UTF-8用的时候直接gbk file | less。这个问题的根源是编码不匹配而不是文件内容本身有问题先判断再转换不要盲目用二进制工具去折腾。5.3 特殊字符、空行与行尾问题有些文件表面上看内容正常但脚本跑起来就是出错这时候猫腻往往藏在看不见的字符里。最典型的例子是Windows系统编辑过的脚本文件行尾是CRLF也就是回车符加换行符而Linux只认LF换行。用cat直接看很难察觉但可以用cat -A把这些不可见字符原形毕露cat -A script.sh输出里所有行尾的^M$就是CRLF的标志$表示行尾^M是回车符。这类问题在跨系统传输文件时很常见解决办法是用dos2unix转换dos2unix script.sh类似的排查还可以配合od来看具体字节od -c file | head能看到每个字节的真实值。遇到“明明内容没问题但程序读不了”的情况先用cat -A扫一遍往往一眼就能定位比瞎猜正则和逻辑靠谱得多。5.4 日志切割后tail跟踪失效这个坑我已经讲过一次但它值得单独拿出来再说一遍因为实战中太多人踩了。服务日志一般都会被logrotate按照大小或者日期切割切割方式是旧日志改名比如app.log变成app.log.1再新建一个空的app.log继续写入。这时候如果你启动的是tail -f app.log它跟踪的还是被改名的旧文件句柄新增内容根本看不到日志看起来就像“停止了”。解决办法是永远用大写-F参数它的全称是--retry会在文件被重建后自动重新打开跟随。我在生产环境里统一使用这个写法tail -F production.log这个看似只是大小写之差实际效果天差地别。另外一个相关的小技巧是如果想在跟踪日志时顺便过滤关键词直接用管道组合tail -F app.log | grep -i error。这样既能实时跟踪又不会被无关内容淹没。5.5 命令选型速查表最后把前面讲的内容做一张速查表方便遇到具体场景时直接对照这也是我在团队里给新人分享时用的版本场景推荐命令核心优势查看小文本文件cat / nl简单直接适合快速确认浏览超大文本文件less按需加载可搜索可跳转只看文件开头head -n 行数轻量秒出结果只看文件结尾tail -n 行数轻量秒出结果实时跟踪日志tail -F日志切割后依然有效按关键词检索grep -n -C 3定位行号并显示上下文截取行号区间sed -n 10,20p精确切片不读全文件按列拆分与统计awk字段级分析适合统计报表二进制文件查看hexdump -C / od -A x -t x1z按字节展示真实内容文本文件对比diff -u统一格式变更一目了然二进制文件对比cmp快速定位首个差异字节这张表完全可以复制到自己的笔记里用到时再对照细节参数效率比自己翻手册高不少。我个人在实际操作中的体会是Linux文件查看命令从来不是“越高级越好”而是“越匹配越好”。cat有它的价值less有它的场景awk有它不可替代的统计能力真正的高手不是每种命令都能背出几十个参数而是能在看到文件的一瞬间想清楚它是什么类型、有多大、我要从中得到什么然后顺手挑出最合适的那条命令。上面这套方法是我在无数次线上排障中反复打磨出来的踩过的坑也都写在了对应的小节里。如果你把这些组合和注意事项用顺手了处理日志、排查问题、分析文本都会轻松不少这也是我写这篇文章最想传达的东西。
返回列表