Linux基础-08-文本三剑客
文本三剑客
- grep:文本过滤(模式:pattern)工具
grep, egrep, fgrep(不支持正则表达式搜索) - sed:stream editor,文本编辑工具
- awk:Linux上的实现gawk,文本报告生成器
grep
介绍
grep: Global search REgular expression and Print out the line
- 作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行
模式:由正则表达式字符及文本字符所编写的过滤条件
grep [OPTIONS] PATTERN [FILE…]
grep root /etc/passwd
grep "$USER" /etc/passwd grep '$USER' /etc/passwd
grep $(whoami) /etc/passwd
选项
–color=auto: 对匹配到的文本着色显示
-m # 匹配#次后停止
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息
-A # after, 后#行
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系
grep –e 'cat' -e 'dog' file
-w 匹配整个单词
-E 使用egrep
-F 相当于fgrep,不支持正则表达式
-f file 根据模式文件处理
示例
1.显示/proc/meminfo文件中以大小s开头的行(2种方式)reg: ^[Ss]
grep "^[Ss]" /proc/meminfo
grep -i "^s" /proc/meminfo
2.显示/etc/passwd文件中不以/bin/bash结尾的行reg: /bin/bash$
grep -v "/bin/bash$" /etc/passwd
3.如果root用户存在,显示其默认的shell程序 位置锚定[root@test tmp]# id root > /dev/null && grep "^root\>" /etc/passwd | cut -d: -f7
4.找出/etc/passwd中的两位或三位数 ; 贪婪匹配 –> 继续往后匹配reg: [[:digit:]]\{2,3\}
[root@test tmp]# grep "\<[[:digit:]]\{2,3\}\>" /etc/passwd
[root@test tmp]# grep "\<[0-9]\{2,3\}\>" /etc/passwd
[root@test tmp]# grep -E "\<[0-9]{2,3}\>" /etc/passwd
– 使用ERE
5.显示/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面存非空白字符行reg : ^[[:space:]]\+[^[:space:]]\+
[root@test tmp]# grep "^[[:space:]]\+[^[:space:]]\+" /etc/grub2.cfg
6.找出“netstat -tan”命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行reg: LISTEN[[:space:]]*$
netstat -tan | grep "LISTEN[[:space:]]*$"
7.添加用户bash、testbash以及nologin(其shell为/sbin/nologin),然后找出/etc/passwd文件中用户名同shell名的行useradd bash && useradd testbash && useradd nologin -s /sbin/nologin
bash:x:1010:1013::/home/bash:/bin/bash
nologin:x:1012:1015::/home/nologin:/sbin/nologin
reg: [[:alnum:]]\+
扩展正则:[root@test tmp]# grep -E "^(\<[[:alnum:]]+\>).*\1$" /etc/passwd
基本正则:[root@test tmp]# grep "^\(\<[[:alnum:]]\+\>\).*\1$" /etc/passwd
\1 : 引用分组的内容;保证用户名和shell同名
sed
介绍
- Stream EDitor, 行编辑器
- sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
- 功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
- 参考: http://www.gnu.org/software/sed/manual/sed.html
用法
sed [option]... 'script' inputfile...
常用选项:
- -n 只打印匹配到的行
- -e 多点编辑
- -f /PATH/SCRIPT_FILE 从指定文件中读取编辑脚本
- -r 支持使用扩展正则表达式
- -i.bak 备份文件并原处编辑
script:
- ‘地址命令’
地址定界:
不给地址:对全文进行处理
单地址:
#:指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行
地址范围:
x,y 从x行到y行
x;y 第x行和第y行
x,+y x后y行
x,y! : 从x,y行之外
/pat1/,/pat2/ 查询包含两个模式的行
#,/pat1/ #行后查询包含匹配模式的行
/pat1/,# #行内查询包含匹配模式的行
~:步进, 第一个数为起始行后一个数字为前进步数
- 1~2 奇数行
- 2~2 偶数行
编辑命令:
- d 删除模式空间匹配的行,并立即启用下一轮循环
- p 打印当前模式空间内容,追加到默认输出之后
- a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
- i [\]text 在行前面插入文本
- c [\]text 替换行为单行或多行文本
- w /path/file 保存模式匹配的行至指定文件
- r /path/file 读取指定文件的文本至模式空间中匹配到的行后
- = 为模式空间中的行打印行号
- ! 模式空间中匹配行取反处理
高级编辑命令:
- P: 打印模式空间开端至\n内容,并追加到默认输出之前
- h: 把模式空间中的内容覆盖至保持空间中
- H:把模式空间中的内容追加至保持空间中
- g: 从保持空间取出数据覆盖至模式空间
- G:从保持空间取出内容追加至模式空间
- x: 把模式空间中的内容与保持空间中的内容进行互换
- n: 读取匹配到的行的下一行覆盖至模式空间
- N:读取匹配到的行的下一行追加至模式空间
- D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,
并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间
不包含换行符,则会像发出d命令那样启动正常的新循环 - q: 第一个模式匹配后立即退出
- {}: 在定位执行行的命令组,用;进行分隔
s/// 查找替换,支持使用其它分隔符,s@@@,s###
替换标记:
- g 行内全局替换
- p 显示替换成功的行
- w /PATH/FILE 将替换成功的行保存至文件中
注意: -i 和 -n 不能一起使用
示例
sed ‘2p’ /etc/passwd
显示/etc/passwd的第2行sed -n ‘2p’ /etc/passwd
不显示/etc/passwd的第2行sed -n ‘1,4p’ /etc/passwd
sed -n ‘/root/p’ /etc/passwd
sed -n ‘2,/root/p’ /etc/passwd
从2行开始sed -n ‘/^$/=’ file
显示空行行号sed -n -e ‘/^\$/p’ -e ‘/^$/=’ file
sed‘/root/a\superman’ /etc/passwd
行后sed ‘/root/i\superman’ /etc/passwd
行前sed ‘/root/c\superman’ /etc/passwd
代替行sed ‘/^$/d’ file
sed ‘1,10d’ file
nl /etc/passwd | sed ‘2,5d’
nl /etc/passwd | sed ‘2a tea’
sed 's/test/mytest/g' example
sed –n ‘s/root/&superman/p’ /etc/passwd
单词后sed –n ‘s/root/superman&/p’ /etc/passwd
单词前sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
sed –i.bak ‘s/dog/cat/g’ pets
sed -n 'n;p' FILE
sed '1!G;h;\$!d' FILE
sed ‘N;D’FILE
sed '$!N;$!D' FILE
sed '$!d' FILE
sed ‘G’ FILE
sed ‘g’ FILE
sed ‘/^$/d;G’ FILE
sed 'n;d' FILE
sed -n '1!G;h;$p' FILE
ls test*.txt|sed -r 's#(.*)txt#mv & \1jpg#g'
只打印文本的第1到4行内容
[root@test tmp]# sed -n '1,4p' fstab
只打印文本中包含xfs的行
[root@test tmp]# sed -n '/xfs/p' fstab
只打印文本中以UUID开头的行
[root@test tmp]# sed -n '/^UUID=.*/p' fstab
显示文件中以UUID开头行的行号
[root@test tmp]# sed -n '/^UUID=.*/=' fstab
在/etc/hosts文件中第3行位置添加主机名解析内容
[root@test tmp]# sed -i '2a\192.168.10.10 node1' /etc/hosts
删除上述添加的解析内容
[root@test tmp]# sed -i '3d' /etc/hosts
替换以UUID开头行的内容
[root@test tmp]# sed -i '/^UUID=.*/c\test......' fstab
将fstab文件中以#开头的所有内容保存至fstab_part文件中
[root@test tmp]# sed '/^#.*/w fstab_part' fstab
将fstab_part文件内容读写到1.txt文件中第2行以后位置
[root@test tmp]# sed -i '2r fstab_part' 1.txt
将1.txt文本中hello替换成全局替换成大写
[root@test tmp]# sed -i 's/hello/HELLO/g' 1.txt
将替换的内容保存至1_part.txt文本中
[root@test tmp]# sed 's/HELLO/Hi/g w 1_part.txt' 1.txt
显示/etc/passwd文件中位于第偶数行的用户的用户名
sed -n 'n;p' /etc/passwd | cut -d: -f1
为/tmp/1.txt 文件中前三行的行首加#号。
sed -i '1,3s@\(^.\)@#\1@g' /tmp/grub.conf
1,3s@\(^.\)@#\1@g
sed "1,3s/(.*)/#\1/"
取消注释行:
sed '1,10s@^#\(.*\)$@\1@g' 1.txt
^#+(.*)$ —> 查询内容:所有#开头的行
\1 替换的内容 (.*)
awk
awk介绍
- awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出
- 有多种版本:New awk(nawk),GNU awk( gawk)
- gawk:模式扫描和处理语言
- 基本用法:
- awk [options] ‘program’ var=value file…
- awk [options] -f programfile var=value file…
- awk [options] ‘BEGIN{action;… }pattern{action;… }END{action;… }’ file …
- awk 程序可由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成
- program 通常是被放在单引号中
- 选项:
- -F “分隔符” 指明输入时用到的字段分隔符
- -v var=value 变量赋值
awk语言
- 基本格式:awk [options] ‘program’ file…
- Program:pattern{action statements;..}
- pattern和action
- pattern部分决定动作语句何时触发及触发事件
BEGIN,END - action statements对数据进行处理,放在{}内指明
print, printf
- pattern部分决定动作语句何时触发及触发事件
- 分割符、域和记录
- awk执行时,由分隔符分隔的字段(域)标记$1,$2…$n称为域标识。$0为所有域,注意:此时和shell中变量$符含义不同
- 文件的每一行称为记录
- 省略action,则默认执行 print $0 的操作
awk工作原理
- 第一步:执行BEGIN{action;… }语句块中的语句
- 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
- 第三步:当读至输入流末尾时,执行END{action;…}语句块
- BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
- END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
- pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
awk变量
- 变量:内置和自定义变量
- 自定义变量(区分字符大小写)
- -v var=value
- 在program中直接定义
- FS:输入字段分隔符,默认为空白字符
awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
awk –F: '{print $1,$3,$7}’ /etc/passwd
- OFS:输出字段分隔符,默认为空白字符
awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
- RS:输入记录分隔符,指定输入时的换行符
awk -v RS=' ' ‘{print }’ /etc/passwd
- ORS:输出记录分隔符,输出时用指定符号代替换行符
awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
- NF:字段数量(列)
awk -F:‘{print NF}’ /etc/fstab
引用变量时,变量前不需加$awk -F:‘{print $(NF-1)}' /etc/passwd
- NR:记录号(行)
awk ‘{print NR}’ /etc/fstab ; awk END‘{print NR}’ /etc/fstab
- FNR:各文件分别计数,记录号
awk '{print FNR}' /etc/fstab /etc/inittab
- FILENAME:当前文件名
awk '{print FILENAME}’ /etc/fstab
- ARGC:命令行参数的个数
awk '{print ARGC}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
- ARGV:数组,保存的是命令行所给定的各参数
awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab
- 示例:
awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello,gawk";print test}'
awk -F:‘{sex=“male”;print $1,sex,age;age=18}’ /etc/passwd cat awkscript {print script,$1,$2}
awk -F: -f awkscript script=“awk” /etc/passwd
print&printf命令
- print格式:print item1, item2, …
- 要点:
(1) 逗号分隔符
(2) 输出item可以字符串,也可是数值;当前记录的字段、变量或awk的表达式
(3) 如省略item,相当于print $0 - 示例:
awk '{print "hello,awk"}'
awk –F: '{print}' /etc/passwd
awk –F: ‘{print “kong”}’ /etc/passwd
awk –F: ‘{print $1}’ /etc/passwd
awk –F: ‘{print $0}’ /etc/passwd
awk –F: ‘{print $1”\t”$3}’ /etc/passwd
grep “^UUID”/etc/fstab| awk ‘{print $2,$4}’
格式化输出:printf “FORMAT”, item1, item2, …
(1) 必须指定FORMAT
(2) 不会自动换行,需要显式给出换行控制符,\n
(3) FORMAT中需要分别为后面每个item指定格式符格式符:与item一一对应
- %c:显示字符的ASCII码
- %d, %i:显示十进制整数
- %e, %E:显示科学计数法数值
- %f:显示为浮点数
- %g, %G:以科学计数法或浮点形式显示数值
- %s:显示字符串
- %u:无符号整数
- %%:显示%自身
修饰符
- #[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
- - 左对齐(默认右对齐) %-15s
- + 显示数值的正负符号 %+d
示例
awk -F: ‘{printf "%s",$1}’ /etc/passwd
awk -F: ‘{printf "%s\n",$1}’ /etc/passwd
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F:‘ {printf "Username: %s\n",$1}’ /etc/passwd
awk -F: ‘{printf “Username: %s,UID:%d\n",$1,$3}’ /etc/passwd
awk -F: ‘{printf "Username: %15s,UID:%d\n",$1,$3}’ /etc/passwd
awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}’/etc/passwd
操作符
算术操作符:
- x+y, x-y, x*y, x/y, x^y, x%y
- -x:转换为负数
- +x:将字符串转换为数值
字符串操作符:没有符号的操作符,字符串连接
赋值操作符:
=, +=, -=, *=, /=, %=, ^=,++, –比较操作符:
==, !=, >, >=, <, <=模式匹配符:
- ~:左边是否和右边匹配,包含
- !~:是否不匹配
- 示例:
awk -F: '$0 ~ /root/{print $1}‘ /etc/passwd
awk '$0~“^root"' /etc/passwd
awk '$0 !~ /root/‘ /etc/passwd
awk -F: ‘$3==0’ /etc/passwd
逻辑操作符:与&&,或||,非!
示例:awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd
awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
awk -F: ‘!($3==0) {print $1}' /etc/passwd
awk -F: ‘!($3>=500) {print $3}’ /etc/passwd
条件表达式(三目表达式)
selector?if-true-expression:if-false-expression
示例:awk -F: '{$3>=1000?usertype="Common User":usertype=" SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
awk PATTERN
PATTERN:根据pattern条件,过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配每一行
(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
awk'/^UUID/{print $1}' /etc/fstab
awk'!/^UUID/{print $1}' /etc/fstab
(3) relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
示例:
awk -F: 'i=1;j=1{print i,j}' /etc/passwd
awk ‘!0’ /etc/passwd ; awk‘!1’ /etc/passwd
awk -F: '$3>=1000{print $1,$3}' /etc/passwd
awk-F: '$3<1000{print $1,$3}' /etc/passwd
awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
(4) line ranges:行范围
- startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
awk -F: ‘/^root\>/,/^nobody\>/{print $1}' /etc/passwd
awk -F: ‘(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
(5) BEGIN/END模式
BEGIN{}:仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
示例:
awk -F : ‘BEGIN {print “USER USERID”} {print $1“:”$3} END{print “END FILE"}' /etc/passwd
awk -F : '{print "USER USERID“;print $1":"$3} END{print "END FILE"}' /etc/passwd
awk -F: 'BEGIN{print " USER UID \n--------------- "}{print $1,$3}' /etc/passwd
awk -F: ‘BEGIN{print “ USER UID \n--------------- ”}{print $1,$3}’END{print “==============”} /etc/passwd
seq 10 | awk 'i=0'
seq 10 | awk 'i=1'
seq 10 | awk 'i=!i'
seq 10 | awk'{i=!i;print i}'
seq 10 | awk‘!(i=!i)'
seq 10 | awk-v i=1 'i=!i'
awk action
常用的action分类
(1) Expressions:算术,比较表达式等
(2) Control statements:if, while等
(3) Compound statements:组合语句
(4) input statements
(5) output statements:print等
更多请参看https://www.runoob.com/w3cnote/awk-built-in-functions.html#b2