【liinux系统(shell脚本):第二章 文本三剑客】

本文介绍了正则表达式的概念及其在grep、AWK和SED这三个文本处理工具中的应用,包括字符匹配、重复次数、锚定、分组和捕获等内容,以及实战中的常见使用场景和面试问题解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式

类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。

正则表达式由特定的字符和操作符构成,用来描述字符串的模式。以下是一些常见的正则表达式操作符和字符:

  1. 字符匹配:
  • .: 匹配任意字符(除了换行符)。
  • [...]: 匹配括号中的任意一个字符。
  • [^...]: 匹配不在括号中的任意字符。
  1. 重复次数:
  • *: 匹配前面的元素零次或多次。
  • +: 匹配前面的元素一次或多次。
  • ?: 匹配前面的元素零次或一次。
  • {n}: 匹配前面的元素恰好 n 次。
  • {n,}: 匹配前面的元素至少 n 次。
  • {n,m}: 匹配前面的元素至少 n 次,但不超过 m 次。
  1. 特殊字符:
  • \: 转义字符,用来转义特殊字符,使其失去特殊含义。
  • ^: 表示匹配字符串的开头。
  • $: 表示匹配字符串的结尾。
  • \b: 表示单词边界。
  • \d: 匹配任意数字字符。
  • \w: 匹配任意字母、数字、下划线字符。
  1. 分组和捕获:
  • (...): 创建一个捕获组,用来捕获匹配的内容。
  • (?:...): 创建一个非捕获组,不捕获匹配的内容。

字符匹配

. 匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[zhou] [0-9] [] [a-zA-Z] [:alpha:]
[^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]

字符和操作符描述的字符串
[:alnum:]字母和数字
[:alpha:]代表任何英文大小写字符,相当于 A-Z, a-z
[:lower:]小写字母
[:upper:]大写字母
[:blank:]空白字符
[:space:]包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白
[:graph:]可打印的非空白字符
[:print:]可打印字符
[:punct:]标点符号
\w匹配单词构成部分,等价于[_[:alnum:]]
\W匹配非单词构成部分,等价于[^_[:alnum:]]
\S匹配任何非空白字符。
\s匹配任何空白字符,包括空格、制表符、换页符等等

.匹配任意字符(除了换行符)加上 \(转义符)成为 \. 表示原来的意思。

匹配次数

  • *: 匹配前面的元素零次或多次。
  • +: 匹配前面的元素一次或多次。
  • ?: 匹配前面的元素零次或一次。
  • {n}: 匹配前面的元素恰好 n 次。
  • {n,}: 匹配前面的元素至少 n 次。
  • {n,m}: 匹配前面的元素至少 n 次,但不超过 m 次。

.* 匹配任意字符长度

匹配锚定

^ #行首锚定, 用于模式的最左侧
$ #行尾锚定,用于模式的最右侧
^PATTERN$ #用于模式匹配整行 (单独一行 只有root)
.
^$ #空行
^[[:space:]]*$ # 空白行
.
\broot < 或 \b #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
123\b > 或 \b #词尾锚定,用于单词模式的右侧
\<PATTERN\> #匹配整个单词

分组和捕获

(...): 创建一个捕获组,用来捕获匹配的内容。
(?:...): 创建一个非捕获组,不捕获匹配的内容。

'\([0-9]\{1,3}\.\)\{3\}[0-9]\{1,3\}'      #匹配ip地址

文本三剑客—grep

"文本三剑客"指的是三个经典的文本处理工具:grep、sed 和 awk。

1、正则表达式
正则表达式用于过滤文件中的字符串,与通配符的区别是通配符用于匹配文件名。

标准输出:命令执行结果正确后反馈的结果

标准输入:输入进系统的命令

错误输出:命令执行结果错误后反馈的结果

常用: ^ :表示以…开头 ^n以n开头

           $ :表示以...结尾  n$ 以n结尾

          ^$ :表示过滤空行,以什么开头和结尾中间什么都没有

  管道符 |:只支持有标准输出的命令

 重定向 >:改变标准输出的方向,输出到文件中,输出到其他的远程连接

2、grep命令
过滤想要的文件内容或文件名

使用格式:
①过滤想要的文件内容,cat [选项] 文件名 | grep [选项] “想要的内容”
②过滤想要的文件名称,ls [选项] 文件名 | grep [选项] “想要的文件名”
grep[选项]:

             -v 反选

             -o 只显示匹配字符

             -i 忽略大小写

             -r 递归,快速过滤但是不过滤软连接内容

             -R 递归,快速过滤包括软连接源文件内容

             -n 显示过滤内容在第几行

             -w 把字符串看成单词,除了单词都不要,稍微精确一点

三、本章节涉及面试题目
1、面试题:硬盘满了,该如何解决?
答案:①删除没有用的文件,删除了一个大文件但是磁盘没有释放空间,原因是文件还在被使用。解决方法删除之前:echo “ ”>/大文件。将文件重定向为空。删除之后:lsof | grep delete显示打开的文件并过滤删除的文件,然后kill 杀死这个寻找到的进程。

②申请加硬盘

2、面试题:找到大于7天大于1g的普通文件并删除,一条命令解决。
答案:find -mtime +7 -type f -size +1G -delete

3、面试题:如何将俩个文件合并成一个文件?
答案:上下合成 cat 1.txt 2.txt >3.txt

答案:左右合成 paste 1.txt 2.txt >3.txt

4、面试题:我现在有一个文件夹,有很多文件,请快速过滤出这个文件夹下所有含有root字符串的文件。
答案:grep -rw root 文件夹

5、面试题:实时查看某软件运行的报错日志最后20行,目录/var/log/soft.log
答案: tail -f -n 20 /var/log/soft.log

文本三剑客—AWK

awk的特点:

  • 支持变量、循环、条件语句,可以编写更复杂的脚本。
  • 内置了许多函数,用于处理字符串、数值等。
  • 可以对数据进行格式化、计算、汇总等。

awk的使用格式:
语法:awk ‘pattern {action}’ file
例子:awk ‘/pattern/ {print $1}’ file.txt 会在文件 file.txt 中搜索包含 ‘pattern’ 的行,并打印出每行的第一个字段。({ }为固定格式)

举例:取出sda硬盘的容量
[root@local data]#lsblk 
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   60G  0 disk 
├─sda1            8:1    0    2G  0 part /boot
└─sda2            8:2    0   54G  0 part 
  ├─centos-root 253:0    0   50G  0 lvm  /
  └─centos-swap 253:1    0    4G  0 lvm  [SWAP]
sdb               8:16   0   20G  0 disk 
sdc               8:32   0   20G  0 disk 
sdd               8:48   0   20G  0 disk 
sr0              11:0    1  4.2G  0 rom  
[root@local data]#lsblk  |grep -w sda | awk '{print $4}' #使用awk不指定分隔符(默认是空格) 打印出第4列
60G

[root@local data]#awk -F : '{print $2}' test.txt  #-F 选项 指定分隔符,即指定以什么为分隔符处理内容
 lisi         

awk 'BEGIN{print “1”} END {print “2”} {print “3”} ',首先打印BEGIN后的print 1,然后打印print 3 最后打印END后的print 2,BEGIN表示第一个打印,END表示最后打印

[root@local data]#  awk 'BEGIN{print "1"} END{print "$2"} {print "3"}' test.txt
1
3
2

配合正则表达式使用

[root@local data]#awk   '/^root/,/root$/{print $2}' test.txt  #使用awk配合正则表达式打印出test.txt文件中以root为开头的且以root结尾的第二列
1

比较操作符:==, !=, >, >=, <, <=
逻辑操作符:&&与 并且的关系,||或 或者关系,!非 取反关系
①FS :指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v “FS=:”


[root@local data]#cat a.txt 
a:b:c
[root@local data]#awk -v "FS=:" '{print $2}' a.txt  #使用FS变量指定:为分隔符打印a.txt文件的第二列
b

②OFS:指定输出时的分隔符

[root@local data]#cat a.txt 
a:b:c
[root@local data]#awk -v "FS=:"  -v OFS="==" '{print $1OFS$3}' a.txt 
a==b

③NF:当前处理的行的字段个数即处理行有多少列,默认按空格分列,可指定。

举例
awk -F : '{print NF}'  /etc/passwd  |head -n 1
#指定:为分隔符打印出文件/etc/passwd第一行有多少个字段,即多少列
7
awk -F : '{print $(NF-1)}'  /etc/passwd |head -n 1 
#指定:为分隔符打印出文件/etc/passwd第一行的倒数第二个字段,即倒数第二列
/root

④NR:当前处理的行的行号(序数)

举例
awk -F :   'NR==1{print $1}'  /etc/passwd
#指定:为分隔符打印出/etc/passwd文件第一行的第一个变量,注意模式要写在'模式{}'位置
root                       
awk -F :   'NR>=1 && NR<=3{PRINT $1}' /etc/passwd
#指定:为分隔符打印出/etc/passwd文件大于等于第一行且小于等于第三行的第三个变量
root
bin
daemon

⑤$0:当前处理的行的整行内容

⑥$n:当前处理行的第n个字段(第n列)

⑦FILENAME:被处理的文件名

⑧RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n

if条件判断

if语句:awk的if语句也分为单分支、双分支和多分支

  • 单分支为if(){}
  • 双分支为if(){}else{}
  • 多分支为if(){}else if(){}else{}
举例
awk -F : '{if($3>1000)print $1,$3}' /etc/passwd
#指定:为分隔符过滤passwd文件第三列如果大于1000则大于出第一列和第三列
nfsnobody 65534

文本三剑客—SED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值