linux文本处理三剑客 grep sed awk 实战
文章目录
grep sed awk对比
grep 主要用于查找包含特定字符串的行;
sed, awk 用于处理文本;
awk中支持C语法, 可以有分支条件判断, 循环语句等, 相当与一个小型编程语言.
grep
1. 单个匹配查询
grep -e "zhang" score.txt
2. 多个匹配
grep -e "zhang" -e "li" score.txt
3. grep结合sed 抽取字符串
抽取字符串是一个常用操作. 由于grep的正则表达式不支持分组操作, 需要结合sed来做字符串的抽取.
grep确定特定行, sed 删除两端.
3.1 抽取本机ip地址
# 1. 提取对应行
ifconfig eth0 | grep "inet addr" # 输出结果: inet addr:192.168.100.201 Bcast:192.168.100.255 Mask:255.255.255.0
# 2. 删除两端
ifconfig eth0 | grep 'inet addr:' | sed -e 's/^.*addr://' | sed -e 's/ *Bcast.*$//' # 输出结果 192.168.100.201
3.2 抽取图片地址
echo "background-image: url(/media/images/index/im2.jpg);"| sed -e 's/^.*url(//' | sed -e 's/).*$//'
# 输出 /media/images/index/im2.jpg
也可使用: grep -o
-o: 只显示匹配部分(grep 默认显示整行)
echo "background-image: url(/media/images/index/im2.jpg);"| grep -o '/.*jpg'
# 输出 /media/images/index/im2.jpg
sed
sed也能用于查询, 但主要用于简单的文本编辑, 如 过滤 和 替换
命令 | 含义 |
---|---|
sed [OPTON] 目标文件 | 对目标文件进行 过滤 或 替换 |
可选参数
可选项 | 含义 |
---|---|
p | 打印 |
d | 删除 |
I | 忽略大小写 |
$ | 代表最后一行 |
-n | 仅显示处理后的结果 |
-e | 根据表达式处理 |
1. 打印特定范围的行
head -n 可以输出前n行, 但不能输出特定范围的行
sed -ne '3,5p' 2.txt # 打印3~5行
2. 列出包含root的行, 且root不区分大小写
sed -ne '/root/Ip' 2.txt
3. 删除行
sed -e '4, $d' 2.txt # 删除4行到最后1行, 并显示
4. 插入, 追加, 替换行
不会修改原文件
参数 | 含义 |
---|---|
ni | 在第n行前插入行 |
na | 在第n行后追加行 |
nc | 将第n行替换 |
sed -e '1i iiiiii' 2.txt
sed -e '2a aaaaaa' 2.txt
sed -e '3c cccccc' 2.txt
5. 替换字符串
不会修改原文件
参数 | 含义 |
---|---|
s/oldString/newString/ | 替换 |
6. 替换字符串(修改原文件)
增加参数i代表替换原文件内容
# 备份原始文件
cp 1.txt 2.txt_bak
# 替换原文件字符串
sed -ie 's/nologin/login/' 2.txt
awk
通过awk
可以实现 模糊查询, 按需提取字段 还可以进行判断和简单的运算.
1. 模糊查询
grep不可以通过单个正则表达式匹配多个模式, 而awk可以.
命令 | 含义 |
---|---|
awk ‘/zhang|li/’ score.txt | 搜索含有zhang 或 li 的行 |
# 查看文档内容
[root@node01 export]# cat score.txt
zhangsan 68 99 26
lisi 98 66 96
wangwu 38 33 86
zhaoliu 78 44 36
maq 88 22 66
zhouba 98 44 46
# 搜索含有 zhang 和 li 的学生成绩
[root@node01 export]# cat score.txt | awk '/zhang|li/'
zhangsan 68 99 26
lisi 98 66 96
zhaoliu 78 44 36
2. 指定分隔符, 根据下标显示内容
grep 一般用于显示一整行(-o 也可以只显示匹配的部分), 但awk可以将行分割为各个字段,更具字段显示内容.
命令 | 含义 |
---|---|
awk -F ‘,’ ‘{prnt $1, $2, $3}’ | 将行按逗号分割后, 打印第1, 2, 3字段 ($0代表整行) |
cat score.txt
zhangsan 68 99 26
lisi 98 66 96
wangwu 38 33 86
zhaoliu 78 44 36
maq 88 22 66
zhouba 98 44 46
cat score.txt | awk -F ' ' '{print $1,$2}'
zhangsan 68
lisi 98
wangwu 38
zhaoliu 78
maq 88
zhouba 98
3. 指定打印时的分隔符
命令 | 含义 |
---|---|
awk -F ’ ’ ‘{OFS="\t"}{print $1, $2, $3}’ 1.txt | 将1.txt中的内容按空格分割后, 以制表符为分割符打印 |
OFS选项
选项 OFS= | 分割符 |
---|---|
“字符” | 字符 |
\b | 空格 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 制表符 |
4. 条用awk函数
命令 | 含义 |
---|---|
awk -F ‘,’ ‘{print toupper($2)}’ 1.txt | 讲1.txt中每行的第一个字段转换为大小后并打印 |
5. if语句
命令 | 含义 |
---|---|
awk -F ‘{if($4>60) print $1, $4}’ | 如果字段4大于60则打印 |
awk -F '{if($4>60} print $1, “及格”; else print $1, “不及格”} | 如果字段4大于60则打印及格, 否则打印不及格 |
其它参数
参数 | 含义 |
---|---|
if($0 ~ “aa”) print $0 | 如果这一行包含"aa", 则打印 |
if($1 ~ “aa”) print $0 | 如果第1个字段包含"aa", 则打印 |
if($1 == “aa”) print $0 | 如果第1个字段等于"aa", 则打印 |
也可以省略if简写:
awk -F ' ' '$4>60 {print $0}' score.txt
6. BEGIN END求字段平均值
命令 | 含义 |
---|---|
awk ‘BEGIN{初始化操作}{每行操作} END{结束时操作}’ 文件名 | 先执行初始化操作, 再执行每行操作, 最后执行结束时操作 |
awk -F ' ' 'BEGIN{}{total = total + $4} END {print "ave: " (total / NR)}' score.txt
# 输出: ave: 59.3333