SHELL学习笔记之文本处理三剑客grep/sed/awk

1 篇文章 0 订阅
1 篇文章 0 订阅

linux文本处理三剑客

一.grep

  • 释义:文本过滤器(在大段指定的文件中,按一定的模式 patten)进行过滤
  • 形式:grep 有三种形式:grep egrep fgrep(grep 家族)
  • 全称:Global search regular expression and printout the line(全面搜索研究正则表达式并显示出来)
  • 作用: grep 命令是一种强大的文本搜索工具,根据用户指定的“模式”对目标文本进行匹配检查,打印匹配到的行。
  • 模式(patten):由正则表达式或者字符及基本文本字符所编写的过滤条件
  • 分类:1.基本正则表达式(BRE): grep                       2.扩展正则表达式 (ERE):  egrep                grep   –E
  • gawk 能够识别 ERE 模式,但 sed 编辑器不能
  • 注意:sed 编辑器和 gawk 的正则表达式引擎之间是有区别的,gawk可以使用大多数扩展正则表达式模式符号,并且提供一些额外的 sed编辑器没有的额外过滤功能,但正因为如此,它通常在处理数据流时更慢
  • 正则表达式:由一类特殊字符及文本字符所编写的模式,其中有些字符不表示字符的字面意思,而表示控制或通配的功能
  • 字符匹配:匹配单个任意字符 ( 出现元字符用引号引起来 ""表示弱引用(意味着:双引号中间有变量的话,变量可先被替换) 单引号表示强引用(直接匹配每个字符))

示例:

  • grep 's..n' /etc/passwd          #匹配以s开头以n结尾的四位字符串



  • grep '...t' /etc/passwd          #匹配以t结尾的四字符串


  • 基本正则表达式匹配字数:用在指定字符的后面,用于指定前面的字符要出现的次数
        • *:匹配前面的字符任意次(仅表示次数 0 次 1 次 多次)
        • .*:.表示任意字符 *任意长度 (这才是任意字符任意长度)
        • \?:(?在 bash shell 中有特殊意义 所以要有转义字符):匹配前面的字符 0 次或者一次(前面的字符可有可无)
        • \+:匹配其前面的字符,至少出现一次(一次或者多次)
        • \{m,n\}:匹配前面的字符至少 m 次,至多 n 次                     grep ‘[[:alpha:]]\{1,3\}t’ /etc/passwd
        • \{0,n\}:匹配前面的字符至多 n 次
        • \{m,\}:匹配前面的字符至少 m 次,多则不限
        • ^:行首绑定:出现于模式的最左侧
        • $:行尾绑定:出现于模式的最右侧
                  grep ‘^[[:alpha:]]\{1,3\}t’ /etc/passwd            grep ‘[[:alpha:]]\{1,3\}t$’ /etc/passwd        grep ‘^[[:alpha:]]\{1,3\}t$’ /etc/passwd
        • (^patten$:用于模式匹配整行)  
        • \< :词首绑定,用于单词模式的左侧
        • \>:词尾绑定,用于单词模式的右侧
        • \<pattern\>: 匹配整个单词
                  grep ‘\<[[:alpha:]]\{1,3\}t’ /etc/passwd            grep ‘[[:alpha:]]\{1,3\}t\>’ /etc/passwd


二.sed

  • 释义:stream editor 文本编辑器(用来操作纯 ASCII 码的文本)在操作文本的时候是按行进行操作的 所以也叫行编辑器
  • 类比:那说到这大家应该明白 我们的编辑器分为两类 还有一类叫做全屏编辑器,我们打开一个编辑器,它会占据整个屏幕,然后提供给我们一个编辑窗口,而后我们就可以在编辑窗口中进行操作了(vim vi)
  • sed是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)
    (为什么叫模式空间呢:因为 sed(不是所有的行都处理)可以指定仅仅处理哪些行,所以 sed 可以像 grep 一样做模式过滤的 符合
    模式条件的处理 不符合条件的不予处理 ),接着用sed 编辑命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
  • 符合模式(模式空间中的模式 每次读取一行 匹配模式 编辑命令)做编辑(到底是删除还是显示还是什么 取决于 sed的编辑命令)
  • Sed 主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等
  • 定址:可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包
    括行数表示的那两行)。如 1,3 表示 1,2,3 行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定。
  • Sed 命令格式:
sed [options] 'command' file(s)
sed [options] -f scriptfile(你可以把 sed 理解为一种简单的语言只不过这种语言 仅仅只对文件做编辑 脚本由sed 命令组成) file(s)

[root@wrh-50 ~]# head -n 6 passwd |tail -n 2
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@wrh-50 ~]# sed -n '5,6p' passwd          #p:(与 d 命令一样 前面都要给定址范围的)
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync


  • Sed 文本定位:
  • 匹配元字符:如果 sed 命令所要匹配的目标字符串中包含元字符,需要使用转义符“\”屏蔽所有特殊意义
sed -n '/\:/p' fstab   
# Created by anaconda on Sun Sep 24 20:13:27 2017
  • Sed 使用元字符进行匹配:sed 可以灵活使用正则表达式的元字符进行批匹配
sed -n '/UUID$/p' fstab      #匹配以UUID结尾的行
sed -n '/^UUID/p' fstab      #匹配以UUID开头的行
sed -n '2,6!p' fstab         #!符号:匹配不在指定行号范围内的行


  • Sed 对文本的操作:
d:
sed ‘/^UUID/d’ /etc/fstab
sed ‘/^#/d’ /etc/fstab
sed ‘/^$/d’/etc/fstab           (删除所有空白行 一开始就结束了)
sed ‘1,4d’/etc/fstab            (d 命令可以和地址定界一起使用)
sed –n ‘/^UUID/!d’ /etc/fstab   (对地址定界取反 除了 UUID 开头的行都删除)
a:
sed ‘/^UUID/a \hello sed /etc/fstab’        (追加到每一行符合条件的行后面)
sed ‘/^UUID/a \hello sed\nwestos /etc/fstab’(支持多行追加)
i:
sed ‘/^UUID/i\hello sed\nwestos /etc/fstab’  (追加在符合条件的行前面)
c:
sed ‘/^UUID/c\hello sed\nwestos /etc/fstab’  (替换符合条件的单行或多行文本)
w:
sed ‘/^UUID/w /tmp/fstab.txt’ /etc/fstab     (把/etc/fstab 中UUID 开头的行保存到/tmp/fstab 中)
sed -n‘/^UUID/w /tmp/fstab.txt’ /etc/fstab
sed ‘/^UUID/=’/etc/fstab (打印行号)
sed ‘6r /etc/issue’ /etc/fstab                (把/etc/issue 文件内容放置到/etc/fstab 中的第六行)
  • Sed -e 的用法:将下一个字符串解析为 sed 编辑命令
  • sed查找并替换:
sed ‘s/oot/OOT/’ /etc/fstab     (把/etc/fstab 中的 oot 变成大写的 OOT)
sed ‘s/^\//#/’/etc/fstab        (把行首的/换成#)
sed ‘s@^/@#@g’/etc/fstab        (如果不想用转义字符的话 可以换转义字符啦~)
sed ‘s/\//#/’/etc/fstab         (默认动作只替换第一次被模式匹配到的串)
sed ‘s/\//#/g/’/etc/fstab

三.awk

  • 三位创始人名字的缩写 文本报告生成器 (能够将给定文本以非常美观的形式显示出来)
  • linux 上面默认使用 gawk


awk '{print $1,$3}' /etc/passwd     (发现与 cat /etc/passwd所输出的内容一样 因为 passwd 这个文件的每一行里面,就没有空格符号阿 )

awk -F: '{print $1,$2}' passwd        #显示当前目录下的passwd文件 第一段和第二段 以:隔开  输出时默认空格分割

awk -F: '{print $1","$2}' passwd      #显示当前目录下的passwd文件 第一段和第二段 以:隔开  输出时以,分割 


  • -F参数示例
awk -F "in" '{print $1, $3}' /etc/passwd
awk -F [:/] '{print $1, $10}' /etc/passwd (awk 还识别多种单个的字符串,比如“:或者/分隔,输出第 1,10 个字段
  • awk 内置常用变量:
  • 注意:调用 awk 的内置变量时,不需要加前置$符号
测试文件: head -n 7 /etc/passwd > passwd.txt
awk '{print FILENAME,NR}' passwd.txt        (使用 awk 输出当前操作的文件名,当前处理的行号)
awk -F: '{print NR,NF}' passwd.txt          (输出每次处理的行号,以及当前行以:,分隔的字段个数)
awk '{print "第"NR"行","有"NF"列"}' passwd.txt

  • awk 处理机制:
  • awk 会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行做一些总结性质的工作,在命令
    格式上分别体现如下
  • BEGIN{}:读入第一行文本之前执行,一般用来初始化操作
  • {}:逐行处理:逐行读入文本执行相应的处理,是最常见的编辑指令块
  • END{}:处理完最后一行文本之后执行,一般用来输出处理结果

            //预处理时,行数为 0

            //全部处理完以后,行数为已读入文本行数

  • awk练习:
输出本机的 IP 地址:
ifconfig br0 | grep 'inet ' | awk '{print $2}'    #br0方式
输出本机的根分区使用率:
df -hT / | tail -1 | awk '{print $6}'

-h(或者 human) :以可读性较高的方式来显示
-T :显示文件系统的类型

  • 前提:
  • 对/etc/passwd 文件有一个详细的认知:
  • /etc/passwd 文件中,一行记录对应着一个用户,每行记录又被冒号(:)分隔为 7 个字段,其格式和具体含义如下:
  • 用户名:口令:用户标识号(UID):组标识号(GID):注释性描述:主目录(也就是用户起始的工作目录):登陆 shell(用户登陆后,
    要启动一个进程,负责将用户的操作传给内核,这个进程是用户登录到系统后运行的命令解释器或某个特定的程序,即 shell shell 是用户与 linux 系统之间的接口)

输出第三行的用户记录: awk -F: 'NR==3{print}' passwd.txt
输出奇数(行号 NR 除以 2 余数为 1)行的用户记录:    awk -F: 'NR%2==1{print}'passwd.txt
输出偶数(行号除以 2 余数为 0)行的用户记录:  awk -F: 'NR%2==0{print}' passwd.txt
输出前三行文本: awk -F: 'NR<=3{print}' passwd.txt
输出从第五行开始到文件末尾的所有行: awk -F: 'NR<=5{print}' passwd.txt
输出用户名为‘sync’的行:   awk -F: '$1=="sync"{print}' passwd.txt


条件设置多个条件的组合示例:
1 && 2 : 1 执行完成(成功)接着执行 2
1 || 2:1 执行完成(不成功)接着执行 2
awk –F:’$3>=0&&3<2{print $1,$3}’/etc/passwd (列出 UID 小于2 的用户信息)
awk –F ‘$3==1||$3==7{print $1,$3}’/etc/passwd (列出 UID 为1 或者 7 的用户信息)

逻辑测试小练习:
测试文件 passwd.txt
输出第 3~5 行文本 : awk -F: 'NR>=3&&NR<=5{print}' passwd.txt
输出第 3 行和第五行文本: awk -F: 'NR==3&&NR==5{print}' passwd.txt
输出 UID 小于 3 或者 UID 是偶数的用户记录:awk -F: '$3<3||$3%2==0{print}' passwd.txt


条件设置变量的数学算示例:
awk -F: '$3>=1&&$3<=4{print}' /etc/passwd (列出 UID 间于 1~的用户详细信息)
awk ‘BEGIN{i=0}{i+=NF}END{print i}’linux.txt (统计文本的总字段个数)
seq 200|awk 'BEGIN{i=0}$(0%3==0)&& \> ($0%13==0){i++}END{print i}' (计算能同时被 3 和 13 整除的整数个数


awk 数学运算练习题:
输出/etc/hosts 影射文件内以 127 或者 129 开头的记录:
a wk -F: '/^127|^192/{print}' /etc/hosts列出 100 以内整数中 7 的倍数或者是含 7 的数(用 awk 来实现 )
此操作无处理文件,正常思路应该是用 shell 循环来完成;因为要求用 awk 来实现,如果不用循化,则根据逐行处理的思路,应该提供一个 100 行的文本对象,
然后将行号作为处理的整数,逐个判断并输出即可
利用 seq 命令可生成 1-100 的整数序列:seq 100
结合管道交给 awk 处理,,那么根据可简化实现步骤。针对本题,行号与每行的
实际文本值是一致的 NR 或者$0 行值进行判断都是可以的:
seq 100 | awk 'NR%7==0||NR~/7/{print}'
seq 100 | awk '$0%7==0||$0~/7/{print}'

awk 流程控制 if 分支结构:

单分支:统计/etc/passwd 文件中 UID 小于或者等于 500 的用户个数“
awk -F: 'BEGIN{i=0}{if($3<=500){i++}}END{print i}' /etc/passwd
统计/etc/passwd 文件中 UID 大于 500 的用户个数:
awk -F: 'BEGIN{i=0}{if($3>500){i++}}END{print i}' /etc/passwd
统计/etc/passwd 文件中登陆 shell 是/bin/bash 的用户个数
awk -F: 'BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}' /etc/passwd
统计/etc/passwd 文件中登陆 shell 不是/bin/bash 的用户个数
awk -F: 'BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}' /etc/passwd


While 循环示例:
统计/etc/passwd 文件内 root 出现的次数
awk -F [:\] \
> 'BEGIN{j=0} \
> {i=1}{while(i<=NF){if($i~/root/){j++};i++}} \
> END{print j}' /etc/passwd
(示例分析:以:或者/做分隔,针对每一行的每一列进行比对,如
果包含 root 则次数加 1 其中:逐行处理直接由 awk 完成,逐列处理交
给 while 循环,通过 i 变量依次取$1,$2...$NF 进行检查;变量 j 在预处
理时赋值 0,每匹配一个子段加 1)

for 示例:awk 'BEGIN{for(i=1;i<5;i++){print i}}'

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值