linux 文本三剑客(grep sed awk)
正则表达式:
意义:处理大量的字符串 处理大量的文本
linux三剑客:
grep :文本过滤工具
sed:流编辑器(对文本替换删除)
awk:将文本格式化再输出
基本正则表达式BRE集合:
匹配字符 匹配次数 位置锚定
^ 尖角号,用于模式最左侧,如'^oldboy', 匹配以oldboy单词开头的行
grep -ni "^i" passwd 忽略大小并显示行号找出 i开头的行
$ 美元符号
grep -ni "\.$" passwd 忽略大小写显示行号并找出.结尾的行
(这里要用到\ 让特殊字符现出原形 \.的意思就是小数点)
^$ 匹配空行
例: grep "^$" passwd -n 匹配passwd文件的空行并显示行号
\ 返斜杠 作用 让特殊字符现出原形 \.的意思就是 .小数点
.点符号
"." 表示任意一个字符 有且只有一个, 不包括空行 (找出除了空行以外的内容)
grep -n "." shiyan.txt
grep -n ".s" shiyan.txt
"*" 匹配0次或者多次
找出文中出现"i*" 的0次或多次 grep -n "i*" /etc/passwd
.*组合符 .(匹配所有)
grep -n ".*" /etc/passwd
[] 中括号 [a-z] 全大写匹配 [A-Z]全小写匹配 "[^0-5]" 过滤到0-5数字
grep -n [a-z] shiyan.txt 显示行号匹配小写内容在该文件中
grep : grep 参数 执行动作 文件名称
-i 忽略大小写 -n 显示行号 -c统计行号 -v 反向输出 -o 只显示匹配到的关键字
grep -ni root /etc/passwd 找出/etc/passwd文件夹下面的有root的所有行忽略大小写显示行号
grep -ni '^i' /etc/passwd 找出i开头的 忽略大小写的行并显示行号
grep -no root /etc/passwd 显示行号 只输出root
注意:再linux平台下,所有文件的结尾都有一个$符
可以用 cat -En查看文件
扩展正则表达式:
grep -E
+号 表示匹配前一个字符一次或多次 必须用 grep -E 执行
grep -E 'l+' /etc/passwd (出现l的都匹配出来)
?号 表示 找前后出现一次或没有
grep -E 'go?d' shiyan.txt
输出:gd
god
|线 :或
例子:找出系统中txt文件,且名字包含a或b的字符
find / -name "*.txt" | grep -i -E "a|b"
()小括号: 分组过滤被扩起来的内容
{n,m}匹配次数 将前一个字符匹配最少n次,最多m次
grep -E "p{2,4}" test.txt
匹配 p最少出现俩次 最多出现三次
sed流文本编辑器:操作过滤和转换文本内容
sed 选项 sed内置命令字符 输入文件
-n 取消默认输出的
-i直接将修改结果写入文件 (sed操作一开始是直接输入的终端的,加-i参数 才能最终修改到文件中)
-e 多次编辑 不需要管道符
-r 支持正则扩展
sed内置命令字符 用于对文件增删改查
a 对文本增加(对下一行加)
d 删除匹配行
i 插入文本 (对下一行加)
p 打印匹配行内容
s/正则(想匹配的内容)/替换内容/g
sed 匹配范围
空地址: 全文处理
单地址 指定某一行
/ / 被匹配到的每一行
范围区间 10,20(10到20行)10,+5(第10行向下20行), //,//
例子:sed "2,3p" nb.txt #打印输出2到3行 但是这里实际输出了nb.txt中全部内容 因为sed工作机制 符合条件的和不符合条件的都会默认输出
sed "2,3p" nb.txt -n 加-n 参数取消默认输出 这时候才输出2到3行
sed "2,+5p" nb.txt -n 输出从第二行开始加上后面的5行
sed "s/root/my/g" /etc/passwd -i 替换 root为my G为全局替换 g为选中替换
sed "/linux/p" nb.txt -n 打印输出有关键字linux的行
sed"/game/d" nb.txt -i 删除有关game行 并写入文本
sed '2a my fahioashoisa sakldldas' nb.txt -i 在第二行后加入这段话并写入文本
sed '2i my fahioashoisa sakldldas' nb.txt -i 在第二行前面加入这段话并写入文本
\n 换行符 :用于向插入多行文本
sed "3a my nb iasoh\n asiodnio" nb.txt -i 在第三行后写入这段话并插入文本 \n后面的东西插入到下一行
空地址 :不指定地址就是全行处理
sed "a ----------" nb.txt 不指定地址就是在每一行后面加入风格符
例题:只输出eth0 IP
思路:1. 找出eth0 查看到IP在第二行
ifconfig eth0 | sed -e "2s/^.*inet//" -e "2s/net.*$//p" -n
awk:
语法: awk 参数 '模式 {动作}' 文件 awk擅长文本格式化,且输出格式化后的结果 因此print和printf为主要动作
awk内置变量:$n 指定分隔符后,当前记录的第n个字段
$0 完整的输入记录
FS 字段分隔符,默认是空格
NF 字段数量
NR 代表行号
执行awk '{print $2}' chao.txt #打印输出第二列 $0表示整行
自定义输出内容:
awk '{print "第一列:"$1,"第二列:"$3}' chao.txt
输出整行信息$0
awk ‘NR==5{print $0}’ chao..txt #打印输出第五行的全部
awk 'NR==37,NR==40{print NR,$0}' /etc/passwd #打印输出第37行到40行全部 并显示行号
awk变量分为内置变量和自定义变量
内置变量:
{}中内置的NR 表示显示行号
{}中内置的NF 表示显示通过分隔符切割后有多少个字段
FS表示指定分隔符
awk -v FS=':' '{print NR,NF,$0}' hhh.txt # awk默认分割符为空格 通过-v指定分隔符 $0表示全部
1 7 root:x:0:0:root:/root:/bin/bash
2 7 bin:x:1:1:bin:/bin:/sbin/nologin
3 7 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 7 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 7 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
FNR
ORS是输出分隔符的意思 awk默认认为每一行结束 就得添加回车换行符 ORS 可以改变输出符
awk -v ORS='-----CH' '{print NR,$0}' chao.txt
1 pyyu1 pyyu2 pyyu3 pyyu4 pyyu5 -----CH2 pyyu6 pyyu7 pyyu8 pyyu9 pyyu10 -----CH3 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15 -----CH4 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20 -----CH5 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25 -----CH6 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30 -----CH7 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35 -----CH8 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40 -----CH9 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45 -----CH10
内置变量FILENAME 显示awk正在处理的文件名字
awk '{print FILENAME,$0}' hhh.txt
hhh.txt root:x:0:0:root:/root:/bin/bash
hhh.txt bin:x:1:1:bin:/bin:/sbin/nologin
hhh.txt daemon:x:2:2:daemon:/sbin:/sbin/nologin
hhh.txt adm:x:3:4:adm:/var/adm:/sbin/nologin
变量ARGC ARGV
ARGV里村的是参数的内容
awk 'BEGIN{print "我要开始用awk"} {print ARGV[0],AGRV[1],$0}' chao.txt
我要开始用awk
awk chao.txt pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
awk chao.txt pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
awk chao.txt pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
awk chao.txt pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
awk chao.txt pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
awk chao.txt pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
awk chao.txt pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
awk chao.txt pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
awk chao.txt pyyu41 pyyu42 pyyu43 pyyu44 pyyu4
awk chao.txt pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
自定义变量:
通过-v 修改内置变量
awk '{print $1,$(NF-1),$(NF-2)}' chao.txt #打印输出第一列 倒数第二列 倒数第三列
awk格式化输出:
print和printf区别:printf需要指定格式,print不要 print不会自动打印换行符