cat & less & tail & vim 日志

主要是用来处理日志,后端这个岗几乎每天都要跟日志打交道。服务出故障了来查日志,用户有问题要查日志……

一般来说,查日志要么就登录 ElasticSearch等服务搜索,要么就直接对日志文件做查询,所以熟悉日志处理的各种命令,是很重要的。

cat

输出文件的全部内容,不会分页

输出文件内容

cat filename

创建新文件

cat > newfile

合并文件内容

cat file1 file2 > file3

创建 file3 文件,并将 file1 和 file2 先后写入新创建的 file3 中

追加内容到文件

cat >> existingfile

将终端输入的内容追加到 existingfile.txt 的末尾(不会覆盖)

将文件内容写入另一个文件

cat filename > newfile.txt,会覆盖 newfile.txt 的原有内容

合并文件并显示内容

cat file1 file2

清空文件内容

cat /dev/null > filename

参数

-n 显示行号

-v 显示特殊字符
-b 显示非空行的行号

less

cat命令会把整个文件内容全部输出。要知道,日志文件都是很大的,一次性打印只会狂刷控制它,除了闪瞎眼之外没有其他用处。需要使用less命令,逐行逐页地打印日志内容,再输入”/“使用搜索功能,才能方便我们查看日志。

分页查看文件内容:

less file.txt

  • 空格 向下翻页,b 向上翻页,q 退出。
  • 鼠标滚轮也可以自由滚动查看页面
  • / 输入关键词后回车,可向下搜索(按 n 跳转到下一个匹配项)。
  • ? 输入关键词后回车,可向上搜索(按 N 跳转到上一个匹配项)。

参数

-N 显示行号

less -N newfile.txt

+ 从指定行开始查看

less +100 newfile.txt

-S 查看宽表禁用自动换行
-i 搜索忽略大小写

less -i newfile.txt

进入 less 界面后,输入 /ERROR可匹配 error

tail

显示文件末尾的数据

有时候我们需要一边运行程序,一边实时观察日志打印的内容。就需要tail -f命令,它会一直监听日志变化,并实施打印日志新增内容。还可以和grep命令结合起来只打印我们感兴趣的内容。

查看文件末尾数据:

tail filename.txt

查看管道输入的末尾内容:

sh xxx.sh | tail

将脚本的输出传递给 tail,打印出最后几次的脚本输出

参数

参数 用途与示例
-n <行数> 显示最后 N 行: tail -n 20 filename.txt
(显示最后 20 行)
-f 实时跟踪文件更新(常用于监控日志): tail -f app.log
-F 增强版实时跟踪(文件被轮转或删除后仍继续跟踪): tail -F app.log
-q 静默模式(不显示多文件名称): tail -q file1.txt file2.txt
-s <秒数> 设置监控间隔(与 -f
配合使用): tail -f -s 5 app.log
(每 5 秒刷新)
-c <字节数> 按字节输出末尾内容: tail -c 100 filename.txt
(显示最后 100 字节)
--pid=<PID> -f
结合,当指定进程结束时停止跟踪: tail -f --pid=1234 app.log
-n xx 显示最后 n 行

tail -n 10 app.log显示倒数十行

但是数字前加上’+’就变成正向开始的十行
tail -n+10 app.log 从第十行开始显示直到文件末尾
再配合 head 命令可以实现只输出第 n 行的效果
tail -n+10 app.log | head - 1
-1 表示只输出head接收到的数据的前1行
类似的,-n表示前n行

-f 实时跟踪文件末尾的新增数据

tail -f app.log

-F 文件被改名后仍继续跟踪

tail -F app.log

-s xx 每几秒刷新一次显示内容

tail -f -s 5 app.log每 5 秒刷新

-pid=xxx 当指定进程结束时停止显示内容

tail -f --pid=1234 app.log

经典组合

实时监控日志并显示最后 50 行:

tail -n 50 -f app.log

监控多个日志文件:

tail -f app.log error.log

vim

vim编辑器无需多言,能把 vim 用成 ide 的人是真牛逼。

个人对 vim 的使用仅限于:

  • -i 修改
  • esc 回到普通模式
  • :wq 退出
  • gg 回到开头,G 回到末尾

高频快捷键

快捷键 用途
移动光标
h
j
k
l
左、下、上、右移动。
gg 跳转到文件开头。
G 跳转到文件末尾。
0 跳转到行首。
$ 跳转到行尾。
文本编辑
x 删除当前字符。
dd 删除整行。
yy 复制当前行。
p 粘贴到光标下一行。
u 撤销操作。
Ctrl + r 重做操作。
搜索替换
/关键词 向下搜索关键词(按 n
跳转下一个,N
上一个)。
?关键词 向上搜索关键词。
:%s/old/new/g 全局替换所有匹配的 old
new
(需在命令行模式输入)。

命令行模式常用命令

命令 用途
:w 保存文件。
:q 退出 vim。
:q! 强制退出不保存。
:wq
:x
保存并退出。
:set nu 显示行号。
:set nonu 隐藏行号。
:sp 文件名 水平分屏打开新文件。
:vsp 文件名 垂直分屏打开新文件。

vimtutor

  • 输入vimtutor 可进入交互式教程

ping & telnet & netstat & lsof 网络

排查网络故障也是工作中常见的场景。其中最高频的指令就是ping和telnet,它们一个用来检查主机是否连通和是否有丢包,一个用来检查端口是否连通。

ping

两个作用,一个是用来检测目标网络是否连通,一个是用来检查是否存在丢包的情况。

连通且没有丢包

telnet

用来检查目标某端口是否正常连通。

端口连通

netstat

用来显示当前主机网络状态的指令。

列出本机所有正在监听的 TCP 端口,并显示对应的进程信息

netstat -lntp

  • n 参数表示数字,它可以让netstat以数字形式显示地址和端口号,而不是以名称的形式显示。
  • l 参数表示监听,所以 netstat -l 会显示所有监听的socket。
  • t 参数表示TCP协议,所以 netstat -t 只会显示TCP协议的socket。
  • p 参数表示程序,所以 netstat -p 会显示每个socket对应的程序的信息。

该指令会列出所有在监听状态的socket,并以数字形式显示地址和端口号,同时还会显示与这些socket相关的程序的信息(关注PID号)。一般用来检查主机对外开放的端口。

Mac 系统下的该命令的 p 参数不支持不带参数

图中形如 10.161.102.54.56438 这样的信息表示 ip 地址是10.161.102.54,使用的端口是 56438。

列出本机所有正在监听与没有监听的的 TCP 端口,并显示对应的进程信息

netstat -latp

  • l 参数表示监听,所以 netstat -l 会显示所有监听的socket。
  • a 参数表示所有,所以 netstat -a 会显示所有的socket(监听的与非监听的)。
  • t 参数表示TCP协议,所以 netstat -t 只会显示TCP协议的socket。
  • p 参数表示程序,所以 netstat -p 会显示每个socket对应的程序的信息。

因此,netstat -latp 会列出所有使用TCP协议的socket,无论是正在监听的还是非监听的,同时还会显示与这些socket相关的程序的信息。一般用来检查主机的所有连接。

Mac 系统下的该命令的 p 参数不支持不带参数

lsof

lsof全称是List Open Files,用来列出系统中被打开的文件。因为Linux中一切皆文件,所以这个命令可以查看很多信息,比如进程打开的普通文件、目录、网络连接、设备等。

参数

-u 查看指定用户打开的文件

lsof -u root

-p 查看指定进程打开的文件

lsof -p 1234

-i 查看指定端口的占用

lsof -i 8080

查看占用 80 端口的进程

-c 按进程名过滤

lsof -c nginx

查看进程名包含 “nginx” 的文件

其它用法

查看指定文件或目录的占用

查看正在读写 syslog 的进程

lsof /var/log/syslog

ps & top & df & systemctl 系统

ps

ps(Process Status)用于查看当前系统中的进程状态,可显示进程 ID(PID)、资源占用、运行状态等信息

查看当前终端的进程:

ps

参数

-e 选择所有进程

-f 全格式列表

-p xxx 显示指定进程的信息

-o xxx 允许用户指定想要查看的进程信息字段

参数组合

ps -ef

ps -ef 命令以全格式显示所有进程的状态信息,这将包括每个进程的id,父进程的id,CPU和内存的使用情况,开始时间,运行时间,所属用户,命令行等信息。再使用grep来筛选我们该兴趣的东西。

ps -fp xxx

ps -fp xxx该命令会列出 pid 为 xxx 的进程的详细信息:

ps -fp xxx -o yyyy=zzz

ps -fp xxx -o yyyy=zzz 输出 pid 为 xxx 的进程的 yyyy 字段信息,命名为 zzz

都是用来查看系统资源占用的指令,top指令主要用来查看系统CPU占用、内存占用和负载。df指令只要用来查看系统磁盘占用。

top

直接输入,就会实时刷新当前系统的CPU、内存、负载占用情况。

参数

-p 显示指定进程的资源占用情况

Mac 系统中 p 参数叫 pid

-o xxx 按指定字段降序排序

top -o MEM

htop

以更直观的方式显示进程占用资源情况。其gui 界面支持通过点击实现排序、搜索等功能。

这个命令 Mac 默认不支持,需要通过 brew install htop安装。

df -h

以人类可读的方式打印机器磁盘占用情况。

systemctl

看、控制系统服务的运行情况

如:systemctl restart nginx systemctl stop nginx systemctl start nginx

重定向操作符 > & >>

两个重定向操作符,不同的是 > 会覆盖源文件,>> 会追加到源文件尾部。

bash xx.sh > xxx.log

运行名为 xx.sh 的 shell 脚本,并将该脚本的输出以覆盖写的方式输出到 xxx.log 文件中。

bash xx.sh >> xxx.log

运行名为 xx.sh 的 shell 脚本,并将该脚本的输出以追加写的方式输出到 xxx.log 文件中。

其它工具命令

awk

用于处理结构化文本数据(如按列分隔的文本)。

这个命令有点复杂,模板大概是:

awk [参数] '条件 {动作}' 文件名

参数

-F 指定字段分隔符

awk -F ',' '{print $1}' data.csv(按逗号分隔)

-v 定义变量

awk -v name=John '{print name, $1}' file.txt

-f 用指定脚本处理文件

awk -f script.awk data.txt

script.awk 中定义的规则来处理文件 data.txt

内置变量

  • NR:当前处理的行号,多个文件会累积。如file1.txt 有 8 行,file2.txt 的第 2 行对应全局的第 10 行
  • FNR:当前处理的某文件的行号,每个文件单独计数
  • NF:当前行的字段数量
  • FS:输入字段分隔符(默认空格)
  • OFS:输出字段分隔符(默认空格)
  • FILENAME:当前处理的文件名

用法

提取字段
打印第一列

awk '{print $1}' file.txt

打印最后一列

awk '{print $NF}' file.txt

条件过滤
打印第三列大于 100 的行

awk '$3 > 100 {print $0}' data.txt

匹配包含关键词的行:

awk '/error/ {print $0}' log.txt

计算与统计
计算第一列的总和:

awk '{sum += $1} END {print sum}' data.txt

统计行数:

awk 'END {print NR}' file.txt

格式化输出
调整列顺序并添加分隔符

awk '{print $2 " : " $1}' file.txt

输出表头

awk '{print $2 " : " $1}' file.txt

管道格式化输出

ps -p 40808 -o rss= | awk '{printf"%.2f MB \n" , $1 / 1024}'

将 rss 字段的数值传递给 awk 命令,在 awk 中使用$1 捕获第一个数,因为管道只传递了一个数过来,所以$1捕获的数一定是 rss 字段的值。

将 rss 字段的值除以 1024 后作为 printf 的参数去打印。

注意,printf 中如果不换行会莫名奇妙打印一个百分号%。

打印文件的第十行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
awk 'FNR == 10 {print }'  file.txt
# awk “用于逐行读取文件”
# FNR == 10 “FNR 表示当前文件的行号(针对每个文件单独计数)。FNR == 10 意味着当当前行号是第 10 行”
# {print} “打印当前行内容”
# file.txt “输入文件,awk 将逐行读取该文件的内容”

# FNR 与 NR 的区别,如下面shell:
# awk 'FNR == 10 {print }' file1.txt file2.txt
# FNR 是针对每个文件单独计数,因此会打印每个文件的第 10 行。
# 如果改用 NR,则 NR 是全局行号,会根据所有文件的行数累计。
# 例如,file1.txt 有 8 行,file2.txt 的第 2 行对应全局的第 10 行。

作者:疯子
链接:https://leetcode.cn/problems/tenth-line/solutions/2996353/195-xiang-jie-4fen-shell-by-fengzil-brw0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

也可以这样写:

1
2
3
4
5
cat file.txt | awk -F '\n' '{
if(NR == 10) {
print $1
}
}'

将每一行的内容作为一个整体,如果当前处理的行数等于10就打印

转置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
awk '{ #这个大括号里的代码是 对正文的处理
# NF表示列数,NR表示已读的行数
# 注意for中的i从1开始,i前没有类型
for (i=1; i<=NF; i++){#对每一列
if(NR==1){ #如果是第一行
#将第i列的值存入res[i],$i表示第i列的值,i为数组的下标,以列序号为下标,
#数组不用定义可以直接使用
res[i]=$i;
}
else{
#不是第一行时,将该行对应i列的值拼接到res[i]
res[i]=res[i] " " $i
}
}
}
# BEGIN{} 文件进行扫描前要执行的操作;END{} 文件扫描结束后要执行的操作。
END{
#输出数组
for (i=1; i<=NF; i++){
print res[i]
}
}' file.txt

grep

1. 简单关键字搜索

在 file.txt 中搜索 “keyword”

grep "keyword" file.txt

在多个文件中搜索 keyword

grep "keyword" file1 file2

2. 忽略大小写(-i

grep -i "error" app.log

3. 反向匹配(-v

输出不包含 “success” 的行

grep -v "success" data.csv

4. 统计匹配次数(-c

输出包含 “warning” 的行数

grep -c "warning" app.log

cd

进入某目录

ls

列出当前目录下的文件夹和文件

ls -a可以显示隐藏的文件

ls -l可以显示包括文件权限、所有者、修改时间等更多隐藏信息

rm

删除某目录或某文件

加上-f 参数可强制删除

加上-r 参数可以递归删除某目录下的所有文件

快进到 rm -rf /* 跑路

mv

移动文件或目录到指定目录

chmod

修改某文件或某目录的权限

chmod 755 script.sh # 用户:rwx,组和其他:r-x

linux 系统中用八进制表示权限。

权限共有三种,r(读),w(写),x(执行)

对应的值分别是 4,2,1。

如某用户对 script.sh 的权限是 6,即该用户对 script.sh 拥有读写权限(4 + 2 = 6),但不拥有执行权限。

chmod 命令中包含一个三位数,从高位到低位分别表示用户、文件所属用户组、其它用户三类账户对 script.sh 文件拥有的权限。

chmod 755 script.sh 表示让

用户拥有读写以及执行权限,

文件所属用户组拥有读和执行权限,

其它用户拥有读和执行权限。

mkdir

创建名为 qwer 的目录

mkdir qwer

touch

创建名为 qwer.txt 的空文件

touch qwer.txt

kill

kill -9 30987 强制终止 pid = 30987 的进程