携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详
sed - 流式编辑器
sed原理
语法规则:sed 选项 '处理规则' 文件路径
sed与vim的区别
- sed可以把处理文件的规则事先写好,就可以使用同一套规则处理多个文件,vim只能一个一个的进行编辑
- sed处理文件一次处理一行,即同一时间内存中只有文件的一行,比较适合处理大型文件。
sed命令使用
语法规则:sed 选项 '处理规则' 文件路径
- 处理规则 = 定位+命令
# 定位
1. 没有定位表示所有行
2. 行号定位
n 表示定位到第n行
n,m 表示从第n行到第m行
n;m;... 表示第n行和第m行,指定行以分号进行分隔
3. 正则定位
/正则表达式/ 匹配到正则表达式的行
# 命令
d 删除
p 将每一行内容输出到屏幕
s/正则表达式/新内容/gi 将正则表达式匹配到的内容替换成新内容,{g表示匹配所有,i表示忽略大小写,gi可以不写}
- 选项
-n 取消sed命令的默认输出到屏幕
-i 规则对源文件生效不输出到屏幕,只要不加-i规则就不会对源文件生效只是临时修改
- sed可以和
|配合使用
ifconfig eth0 | sed 's/eth0/ens33/'
head -3 a.txt | sed 's/zhy/ZHY/gi'
- 案例
sed 'p' a.txt
- 结果是每一行都输出两次,第一次输出是命令'p'的规则处理结果,第二次是sed默认输出至屏幕
sed -n 'p' a.txt
- 结果是每一行只有一次输出,和源文件一致,输出的是命令'p'的处理结果,sed默认输出被-n选项取消
sed 'd' a.txt
- 结果是屏幕什么都不会输出。文件从硬盘一行一行读入内存,sed的'd'命令对内存中的每一行数据进行删除操作,由于将内存中的数据删除,规则处理后内存中没有数据,因此规则处理不会向屏幕输出同时由于内存中没有数据了,sed命令也无法读取数据向屏幕输出。
sed '1p' a.txt
- 结果是第一行输出两次,其余行只输出一次,通过定位'1'定位到第一行,第一行执行'p'命令,从第二行开始就不符合定位的规则,因此不再执行'p'命令
sed '1,3d' a.txt
- 第一行和第三行数据不输出
sed '/zhy/p' a.txt
- 结果是只有包含zhy的一行数据会被输出两次,因为定位到了包含zhy的行之后还要执行'p'命令,而没有包含zhy的行不会执行'p'命令
sed 's/zhy/ZHY/gi' a.txt
- 结果是在屏幕上输出zhy全部被ZHY替换的结果,sed默认将规则处理之后的结果输出到屏幕上
awk
awk原理
原理和sed差不多,也是一行一行的进行处理,但是没有-i向文件中写入的选项,并且没有默认输出至屏幕。
awk擅长处理有规则的文本,主要用于做一些格式处理
awk使用
awk 选项 '处理规则' 文件路径
- 选项
-F
指定分隔符,不指定默认就是以空格(不管多少个空格都按一个为准)为分隔符,将每一行数据以分隔符分成几段
-F: 以:为分隔符
-F 以空格为分隔符
- 处理规则=定位+命令
# 命令
{print $n} 输出一行的第n段,当n=0时输出一整行
{print $n, $m} 输出一行的第n段和第m段
# 定位
1. 行号定位
NR == n 定位到第n行
NR >= n && NR <= m 定位到n~m行
NR == n && NR == m 定位到n行和m行
2. 正则定位
/正则表达式/ 匹配到正则表达式的行
$n ~ /正则表达式/ 只用一行的某一段进行正则表达式的匹配
- awk和
|结合使用
ifconfig eth0 | awk 'NR == 2{print $2}' | awk -F. '{print$2}'
- NF
NF是每一行被分成的段数,$NF表示每一行的最后一段
- 案例:以/etc/passwd前四行数据为例
awk -F: '{print$0}' b.txt
- 结果是查看b.txt 和cat b.txt效果一致。以:为分隔符,打印一整行数据
awk -F: '{print$1,$NF}' b.txt
- 以:为分隔符,打印每行的第一段和最后一段
awk -F: 'NR==1{print$1,$NF}' b.txt
- 以:为分隔符,打印第一行的第一段和最后一段
awk -F: 'NR>=2 && NR<=4 {print$1,$NF}' b.txt
- 以:为分隔符,打印2-4行的第一段和最后一段
awk -F: '/m/ {print$1,$NF}' b.txt
- 以:为分隔符,打印匹配到正则表达式的所有行的第一段和最后一段
awk -F: '$6~/m/ {print$1,$NF}' b.txt
- 以:为分隔符,只用一行的第6段和/m/进行匹配
grep - 过滤
grep擅长过滤,将符合过滤规则的内容过滤出来
grep使用
grep 选项 '过滤规则(正则表达式)' 文件,需要注意的是grep命令没有定位功能,是在全部结果中进行过滤。
# -n 显示过滤内容所在的行号
grep -n 'root' /etc/passwd
- 在/etc/passwd文件中过滤包含有root的行,并且显示行号
# -i 忽略大小写
grep -in 'root' /etc/passwd
# -l 判断文件中是否包含过滤规则匹配的内容,如果包含则输出文件名称
grep -l 'root' /etc/passwd # 结果 /etc/passwd
# -r 递归,和-l同时使用,可以扫描目录下的所有文件判断它们是否包含过滤规则匹配的内容,如果包含返回文件名称
grep -rl 'root' /etc/
# grep和管道符结合使用 - grep可以在管道符中获取数据
ps aux | grep python
- ps aux查看当前系统中所有进程,使用grep过滤出和Python相关的进程,默认会将和grep的这条记录也显示出来
[root@VM-4-2-centos ~]# ps aux | grep ssh
root 2777 0.0 0.1 85540 4972 ? Ss Mar23 0:41 /usr/sbin/sshd -D
root 2373176 0.0 0.2 163772 10408 ? Ss 09:28 0:00 sshd: root [priv]
root 2373188 0.0 0.1 156992 5724 ? S 09:28 0:00 sshd: root@pts/0
root 2374910 0.0 0.0 12136 1192 pts/0 S+ 09:40 0:00 grep --color=auto ssh
如果不想要和grep相关的这条进程可以使用一下两种方式进行处理:
1. ps aux | grep ssh | grep -v grep
- grep -v 表示将规则内容过滤掉
2. ps aux |grep [s]sh
- 将需要过滤的进程的第一个字母放在[]中