Linux-文本提取命令(grep、cut、awk、sed)
1.grep
作用:按关键字提取需要的行
# 创建两个测试文本
# a.txt
a 1 abong
b 2 aabong
c 3 aaabong
# b.txt
a:1:abong
b:2:aabong
c:3:aaabong
# 查看文本内容
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# cat b.txt
a:1:abong
b:2:aabong
c:3:aaabong
# 查看第二行的内容
[root@master ~]# cat a.txt | grep 2
b 2 aabong
# 查看除了第二行的内容
[root@master ~]# cat a.txt | grep -v 2
a 1 abong
c 3 aaabong
2.cut
作用:按指定条件提取需要的列
参数 | 作用 |
---|---|
-f | 指定提取第几列 |
-d | 指定分隔符,默认的分隔符是tab键 |
-c | 按字符顺序提取第几个字符 |
# 查看第二行的第三列的信息
[root@master ~]# cat a.txt | grep 2 | cut -f 3
aabong
# 查看除了第二行外的第三列的信息
aabong
[root@master ~]# cat a.txt | grep -v 2 | cut -f 3
abong
aaabong
# 查看除了第二行外的第一、三列的信息
[root@master ~]# cat a.txt | grep -v 2 | cut -f 1,3
a abong
c aaabong
# 查看除了第二行外全部列的信息
[root@master ~]# cat a.txt | grep -v 2 | cut -f 1-
a 1 abong
c 3 aaabong
# 查看除了第二行外的第一到列的信息
[root@master ~]# cat a.txt | grep -v 2 | cut -f 1-3
a 1 abong
c 3 aaabong
# 提取按:分隔的文本的第3列信息
]# cat b.txt | grep 2 | cut -d ":" -f 3
aabong
# 按字符提取第5个字符所在列
# tab键算一个字符
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# cat b.txt | grep 2 | cut -c 6
a
# 按字符提取第m-n个字符所在列
[root@master ~]# cat b.txt | grep 2 | cut -c 5-8
aabo
# -f是按第几列提取,而-c是按第几个字符提取,故-f与-c不能一起用。
# -d指定的分隔符不能是空格,若指定空格,会精确到空格的个数。
[root@master ~]# df -h | grep /dev/mapper
/dev/mapper/rhel-root 18G 4.2G 14G 24% /
[root@master ~]# df -h | grep /dev/mapper | cut -d " " -f 5
# 提取第5列,但是分隔符是一些空格,则无法提取。
[root@master ~]# df -h | grep /dev/mapper | cut -f 5
/dev/mapper/rhel-root 18G 4.2G 14G 24% /
综上,grep、cut能与管道符|连用,可以提取格式化文本的某行、某列、某个区域、某个单元格。但分隔符如果是空格,且空格数量不是规则的,则无法提取。作用是提取出指定文本后,可以作为脚本中循环的输入
3.awk
在介绍awk命令前,先来介绍个小朋友printf
。
printf可以理解为格式化输出。但printf不是系统命令,不可接收文件的输入,也不可使用管道符|,但是可以接收命令结果的输入。
格式:printf '输出类型输出格式' 输出内容
输出类型 | 作用 |
---|---|
%ns | 格式化字符串,n表示长度 |
%ni | 格式化整数,n表示长度 |
%m.nf | 格式化浮点型,m位有效数字,保留n位小数 |
输出格式 | 作用 |
\n | 换行 |
\r | 回车 |
\t | 水平输出制表符,即tab键 |
\v | 垂直输出制表符,即tab键 |
\f | 清楚屏幕 |
\a | 输出警告声音 |
\b | 输出空格键 |
# 按格式定制格式化输出
[root@master ~]# printf '%s \n' a b c
a
b
c
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
# 单引号里面的格式是每一行的输出结果的格式
[root@master ~]# printf '%s %s %s\n' $(cat a.txt)
a 1 abong
b 2 aabong
c 3 aaabong
# print相对于printf,多了一个换行符/n。即print自带换行符,而printf需手工加换行符。
# printf可单独使用,但是print只能在awk命令中使用。
上面说了printf命令是格式化输出,那awk命令就是条件动作格式化输出。
格式:awk '条件1{动作1} 条件2{动作2} 条件{3动作3}' 文件名
# 若无条件,则动作的对象是全部内容。
# 不可见字符要用单引号或者双引号括起来,单引号awk命令已用,此时使用双引号括起不可见字符。
# 在awk命令中使用printf命令作为动作,不可使用%s等数据类型进行格式化。
# $3表示第3列
[root@master ~]# awk '{printf $1 "\t" $3 "\n"}' a.txt
a abong
b aabong
c aaabong
# $0表示所有的列
[root@master ~]# awk '{printf $0 "\n"}' a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# awk '$2<=1{printf $1 "\t" $3 "\n"}' a.txt
a abong
[root@master ~]# awk '$2>1{printf $1 "\t" $3 "\n"}' a.txt
b aabong
c aaabong
awk命令执行过程:取一行数据,检测条件,执行动作,输出结果。再取下一行数据,检测条件,执行动作,输出结果。
# 在这里使用awk命令提取磁盘空间的使用量
[root@master ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/rhel-root 18G 3.3G 15G 19% /
devtmpfs 905M 0 905M 0% /dev
tmpfs 914M 140K 914M 1% /dev/shm
tmpfs 914M 8.8M 905M 1% /run
tmpfs 914M 0 914M 0% /sys/fs/cgroup
/dev/sda1 497M 119M 379M 24% /boot
/dev/sr0 3.5G 3.5G 0 100% /run/media/root/RHEL-7.0 Server.x86_64
[root@master ~]# df -h | grep rhel-root
/dev/mapper/rhel-root 18G 3.3G 15G 19% /
[root@master ~]# df -h | grep rhel-root | awk '{printf $5}'
19%[root@master ~]# df -h | grep rhel-root | awk '{printf $5}' | cut -d '%' -f 1
19
awk命令相对于cut命令较为复杂,但是可以解决分隔符是空格且空格数量不规则的文本的提取问题。对规则的文本,cut命令要更简单。
在这里,介绍两个awk中常用的条件。
①BEGIN{动作}:在对文本进行提取前先执行该动作
②END{动作}:在对文本提取结束后再执行该动作
# BEGIN条件:在对文本进行提取前先执行该动作
[root@master ~]# df -h | grep rhel-root | awk 'BEGIN{printf "HELLO!!!\n"} {printf $5}' | cut -d '%' -f 1
HELLO!!!
19
# 使用BEGIN条件指定分隔符 BEGIN{FS=":"}
[root@master ~]# cat /etc/passwd | grep /bin/bash | awk 'BEGIN{FS=":"} {printf $1"\n"}'
root
abong
# END条件:在对文本提取结束后再执行该动作
[root@master ~]# cat /etc/passwd | grep /bin/bash | awk 'BEGIN{FS=":"}END{print "AAAAA"} {printf $1"\n"}'
root
abong
AAAAA
# print相对于printf,多了一个换行符/n。即print自带换行符,而printf需手工加换行符。
[root@master ~]# cat /etc/passwd | grep /bin/bash | awk 'BEGIN{FS=":"}END{printf "AAAAA\n"} {printf $1"\n"}'
root
abong
AAAAA
综上,总结下awk的作用。即可以提取格式化文本的某行、某列、某个区域、某个单元格。对分隔符是空格,且数量不规则的文本也可以提取。还可以在文本提取前和文本提取后加提示语。
4.sed
作用:对文件或者命令的输出结果进行编辑。是一种轻量级的流编辑器。支持数据的选取、替换、删除、新增。在linux中存在vi或vim编辑器,可直接对文件进行编辑,故sed命令主要用于对命令的输出结果进行编辑,而不直接影响文件实际内容。
格式:sed 选项 '动作' 文件名
选项 | 作用 |
---|---|
-n | 默认要输出整个文件,加-n参数,表示只输出经过sed命令处理的行。 |
-e | 指定动作,该选项可省略,但动作要有。 |
-i | 输出屏幕的结果和文件数据都更改,不加-i则不修改文件的数据,只修改输出屏幕的数据。 |
动作 | 作用 |
na | 在第n行后面追加,可追加多行 |
nc | 替换整行,替换第n行 |
ni | 在第n行前面插入,可插入多行 |
nd | 删除第n行。m,nd 指删除第m行到第n行的数据 |
np | 打印第n行。m,np 指打印第m行到第n行的数据 |
ns | 替换第n行的某个字符串,ns/old_str/new_str/g ,将第n行的old_str替换成new_str。 |
ny | 替换第n行的某个字符串,ny/old_str/new_str/ ,将第n行的old_str按字符顺序替换成new_str。 |
# 打印第二行的结果,不加-n参数,把原内容也显示一遍。加了-n参数,只显示打印的部分,即经过sed处理的部分。
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# sed '2p' a.txt
a 1 abong
b 2 aabong
b 2 aabong
c 3 aaabong
[root@master ~]# sed -n '2p' a.txt
b 2 aabong
[root@master ~]# sed -n '2,3p' a.txt
b 2 aabong
c 3 aaabong
# 输出屏幕的结果删除第2、3行,并不修改文件实际的内容。
[root@master ~]# sed '2,3d' a.txt
a 1 abong
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
# 替换第3行的aaabong为xiaoming
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# sed '3s/aaabong/xiaoming/g' a.txt
a 1 abong
b 2 aabong
c 3 xiaoming
# 多行字符串同时替换
[root@master ~]# sed -e '2s/aabong/dalao/g;3s/aaabong/xiaodi/g' a.txt
a 1 abong
b 2 dalao
c 3 xiaodi
# 替换第一行整行为null
[root@master ~]# sed '1c null' a.txt
null
b 2 aabong
c 3 aaabong
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
# a后面追加 i前面插入
[root@master ~]# cat a.txt
a 1 abong
b 2 aabong
c 3 aaabong
[root@master ~]# sed '2a hello!!!' a.txt
a 1 abong
b 2 aabong
hello!!!
c 3 aaabong
[root@master ~]# sed '2i hello!!!' a.txt
a 1 abong
hello!!!
b 2 aabong
c 3 aaabong
# 指定某行按字符替换,不指定则只全文
[root@master ~]# sed '3y/abong/ABONG/' a.txt
a 1 abong
b 2 aabong
c 3 AAABONG
# 其他用法
# 计算总行数
[root@master ~]# sed -n -e '$=' a.txt
3
# 显示行数及打印每一行的内容
[root@master ~]# sed -e '=' a.txt
1
a 1 abong
2
b 2 aabong
3
c 3 aaabong
总结一下,以上四个命令都可以接收文本的输入或者将其他命令的输出结果作为输入,可以很好的在shell脚本中进行文本的提取,并赋予指定的变量。所以学会使用这几个文本提取的命令还是非常有必要的。