三剑客之grep
一、grep
grep 全称是 Global Regular Expression Print (全局正则表达式打印)
正则表达式的匹配模式分为三种:
Pattern selection and interpretation: -E, --extended-regexp PATTERN is an extended regular expression -G, --basic-regexp PATTERN is a basic regular expression (default) -P, --perl-regexp PATTERN is a Perl regular expression
在CentOS下面,grep -E
主要是用来支持扩展正则表达式,比如|
、&
这些符号,用于grep多条件查询,并非是使用标准正则表达式。在shell下面man grep
看了下,加上-P
(使用Perl的正则引擎)即可过滤出目标数据
1、统计包含关键字的行数(一行存在多个关键字,计数为1)
grep -c "keyword" filename
若文件中有多个关键字,需要统计所有关键字出现的次数
2、grep -oP 'swarm_labels=\K.*
-o参数,输出只包括匹配到的部分,而不是整行。只显示找到的匹配内容。
-P 启用 Perl 兼容正则表达式(PCRE)
\K
: 一个特殊的操作符,清除当前匹配内容的缓冲区。在 \K
之前的内容不会出现在最终的匹配结果中。这意味着在匹配到 swarm_labels=
后,它不会出现在输出中。
cat /etc/ansible/hosts | grep docker_swarm_manager -A 4 | grep swarm-01 | grep -oP 'swarm_labels=\K.*' '["lead-manager", "dp", "es1", "kafka", "logstash", "mysqlm", "opt", "portainer", "systools","dataflow_task", "nacos", "common" ,"oracle"]'
3、grep -i 忽略字符大小写的差别
-v 显示不包含匹配文本的所有行,即反选。如去掉注释行和空行
grep -v "#\|^$" /usr/lib/systemd/system/docker.service
4、grep +关键字 -Anum -Bnum -Cnum
-Anum: after, 表示关键字后面nmu行 -Bnum: before, 关键字前nmu行 -Cnum:context, 关键字前后nmu行
如:grep -C1 “18” test2.txt, 打印字符串“18”和它上一行和下一行的信息
5、-n:显示匹配的行号 加上-n选项后会在匹配到后显示所匹配的字符在哪一行
6、-e:实现多个选项间的逻辑or关系
如:grep –e ‘cat ’ -e ‘dog’ file
grep -E 支持正则
7、-w 精确匹配
8、grep -i -n --color 忽略大小写并显示关键字的颜色
9、比较两个文件的相同处:(-f参数后面作为标准的文件一定不能有空行!、每行结尾也不要有空格才行)
将file2里包含file1里的行,放到file3
grep -xFf file1 file2 > file3
-f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-F 或 --fixed-regexp : 将样式视为固定字符串的列表。
-x --line-regexp : 只显示全列符合的列。
10、grep过滤掉空白行和注释行
$ egrep -v "^[[:space:]]*#|^$" config SELINUX=enforcing SELINUXTYPE=targeted $ egrep -v "^[ \t]*#|^$" config SELINUX=enforcing SELINUXTYPE=targeted
11、过滤非标准输出
$ docker logs --since=2021-05-27 jenkins 2>&1 | grep Asynch
12、正则、精确过滤、\1
egrep -w 'ch(en).*\1' test this is chenzjzjentian,and wang,not waen
13、过滤当前路径下所有文件:grep -nr xxx .(r递归,n显示关键字在某个文件中的行号)
$ grep -nr xx . ./xx.yml:1:xx: ./xx.yml:25: # xx 存放程序的目录名(默认值就是xx) ./xx.yml:39: folder_name: "xx"
14、解决 grep 的多次管道过滤问题
crazy.log
是某个进程不断输出日志的文件
我们使用tail -f crazy.log
来检测日志的产生
我们在前面的基础上利用管道增加一层过滤筛选感兴趣的内容。
那么当再次增加一个过滤是,却没有内容(立即)产生了
tail -f crazy.log | grep Hello | grep Time
解决
tail -f crazy.log | grep --line-buffered Hello | grep Time
二、pgrep
经常要查看进程的信息,包括进程的是否已经消亡,通过pgrep来获得正在被调度的进程的相关信息。pgrep通过匹配其程序名,找到匹配的进程
常用参数
-l 同时显示进程名和PID -o 当匹配多个进程时,显示进程号最小的那个 -n 当匹配多个进程时,显示进程号最大的那个 注:进程号越大,并不一定意味着进程的启动时间越晚
使用实例如:pgrep -l
# pgrep -l nginx 3706 nginx 3707 nginx 3708 nginx
pgrep相当于 ps –eo pid,cmd | awk ‘{print $1,$2}’ | grep KeyWord
# ps -eo pid,cmd | awk '{print $1,$2}' | grep nginx 3706 nginx: 3707 nginx: 3708 nginx:
进程跟踪strace
strace -p 3706
strace -tt -T -v -f -e trace=file -o /data/log/strace.log -s 1024 -p 23489
-tt 在每行输出的前面,显示毫秒级别的时间 -T 显示每次系统调用所花费的时间 -v 对于某些相关调用,把完整的环境变量,文件stat结构等打出来。 -f 跟踪目标进程,以及目标进程创建的所有子进程 -e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称 -o 把strace的输出单独写到指定的文件 -s 当系统调用的某个参数是字符串时,最多输出指定长度的内容,默认是32个字节 -p 指定要跟踪的进程pid, 要同时跟踪多个pid, 重复多次-p选项即可。
pgrep查找的是程序名,不包括其参数
# ps axu | grep name root 1754 0.0 1.7 775664 65024 ? Sl 17:30 0:00 /usr/bin/docker run --rm --ipc=host --net=host --entrypoint /usr/bin/ceph-mon --privileged --group-add=disk --name ceph-418abd02-42a9-11eb-91f4-000c298c369a-mon.node1 -e CONTAINER_IMAGE=docker.io/ceph/ceph:v15 -e NODE_NAME=node1 -v /var/run/ceph/418abd02-42a9-11eb-91f4-000c298c369a:/var/run/ceph:z -v /var/log/ceph/418abd02-42a9-11eb-91f4-000c298c369a:/var/log/ceph:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/crash:/var/lib/ceph/crash:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/mon.node1:/var/lib/ceph/mon/ceph-node1:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/mon.node1/config:/etc/ceph/ceph.conf:z -v /dev:/dev -v /run/udev:/run/udev docker.io/ceph/ceph:v15 -n mon.node1 -f --setuser ceph --setgroup ceph --default-log-to-file=false --default-log-to-stderr=true --default-log-stderr-prefix=debug --default-mon-cluster-log-to-file=false --default-mon-cluster-log-to-stderr=true root 1794 0.0 1.6 775664 62928 ? Sl 17:30 0:00 /bin/docker run --rm --ipc=host --net=host --entrypoint /usr/bin/ceph-crash --name ceph-418abd02-42a9-11eb-91f4-000c298c369a-crash.node1 -e CONTAINER_IMAGE=docker.io/ceph/ceph:v15 -e NODE_NAME=node1 -v /var/run/ceph/418abd02-42a9-11eb-91f4-000c298c369a:/var/run/ceph:z -v /var/log/ceph/418abd02-42a9-11eb-91f4-000c298c369a:/var/log/ceph:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/crash:/var/lib/ceph/crash:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/crash.node1/config:/etc/ceph/ceph.conf:z -v /var/lib/ceph/418abd02-42a9-11eb-91f4-000c298c369a/crash.node1/keyring:/etc/ceph/ceph.client.crash.node1.keyring docker.io/ceph/ceph:v15 -n client.crash.node1
用pgrep查询,不是进程名的,是不会被查到
# pgrep name [root@node1 ~]#