Linux正则表达式分为基础正则表达式和扩展正则表达式,
基础正则表达式
语系对正则表达式的影响
不同语系下, 正则表达式表达的范围不同.
举例:( 验证失败, 可能是语系的转换错误了 )
英文大小写的编码顺序:
- LANG=C : 0 1 2 3 … A B C D … Z a b c d … z
- LANG=zh_CN : 0 1 2 3 … a A b B c C … z Z
因此[A-Z] 在不同语系下表示的范围不同.
为避免语系带来的问题, Linux提供了特殊的符号
| 特殊符号 | 代表意义 |
|---|---|
| [:alnum:] | 英文大小写字符与数字: 0-9, A-Z, a-z |
| [:alpha:] | 任何英文大小写字符: A-Z, a-z |
| [:blank:] | 任何空格键与tab键 |
| [:cntrl:] | 代表键盘的控制按键, CR, LF, Tab, Del |
| [:digit:] | 代表数字, 0-9 |
| [:graph:] | 处理空格符外的其它所有按键 |
| [:lower:] | 小写字符, a-z |
| [:print:] | 任何可被打印字符 |
| [:punct:] | 标点符号: “‘?!;:#$ |
| [:upper:] | 大写字符: A-Z |
| [:space:] | 任何会产生空白的字符: 包括空格键, [TAB], CR |
| [:xdigit:] | 代表十六进制的数字, 0-9. A-F, a-f |
示例:
[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alnum:]]12314ADAvada?/[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep "[:alnum:]"grep: character class syntax is [[:space:]], not [:space:][root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alnum:]]12314ADAvada?/[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alpha:]]12314ADAvada?/[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:upper:]]12314ADAvada?/[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:lower:]]12314ADAvada?/[root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:digit:]]12314ADAvada?/
grep的一些高级选项
核心: grep高级选项包括显示筛选的行号和显示筛选的前几行后几行
grep语法:
grep [-A] [-B] [--color=auto] '查找字符' filename
选项与参数:
-A : after, 表示显示筛选的后几行
-B : before, 表示显示筛选的前几行
示例:
[root@kuaicdn tmp]# dmesg | grep -n 'sda'
350:[ 0.677901] sd 0:0:0:0: [sda] 33554432 512-byte logical blocks: (17.2 GB/16.0 GiB)
351:[ 0.677902] sd 0:0:0:0: [sda] 4096-byte physical blocks
352:[ 0.678667] sd 0:0:0:0: [sda] Write Protect is off
353:[ 0.678668] sd 0:0:0:0: [sda] Mode Sense: 0f 00 00 00
354:[ 0.679468] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
355:[ 0.691855] sda: sda1 sda2 sda3 sda4
356:[ 0.694862] sd 0:0:0:0: [sda] Attached SCSI disk
359:[ 1.806313] XFS (sda3): Mounting V5 Filesystem
360:[ 1.890086] XFS (sda3): Ending clean mount
387:[ 5.525572] XFS (sda2): Mounting V5 Filesystem
388:[ 5.596968] XFS (sda2): Ending clean mount
392:[ 5.667166] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[root@kuaicdn tmp]# dmesg | grep -n -A3 -B2 'sda'
348-[ 0.653501] scsi host0: storvsc_host_t
349-[ 0.653658] scsi 0:0:0:0: Direct-Access Msft Virtual Disk 1.0 PQ: 0 ANSI: 5
350:[ 0.677901] sd 0:0:0:0: [sda] 33554432 512-byte logical blocks: (17.2 GB/16.0 GiB)
351:[ 0.677902] sd 0:0:0:0: [sda] 4096-byte physical blocks
352:[ 0.678667] sd 0:0:0:0: [sda] Write Protect is off
353:[ 0.678668] sd 0:0:0:0: [sda] Mode Sense: 0f 00 00 00
354:[ 0.679468] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
355:[ 0.691855] sda: sda1 sda2 sda3 sda4
356:[ 0.694862] sd 0:0:0:0: [sda] Attached SCSI disk
357-[ 0.702264] random: fast init done
358-[ 1.804298] SGI XFS with ACLs, security attributes, no debug enabled
359:[ 1.806313] XFS (sda3): Mounting V5 Filesystem
360:[ 1.890086] XFS (sda3): Ending clean mount
361-[ 2.206566] systemd-journald[128]: Received SIGTERM from PID 1 (systemd).
362-[ 2.285008] printk: systemd: 12 output lines suppressed due to ratelimiting
363-[ 2.567577] SELinux: Disabled at runtime.
--
385-[ 5.042757] AES CTR mode by8 optimization enabled
386-[ 5.155022] intel_pmc_core intel_pmc_core.0: initialized
387:[ 5.525572] XFS (sda2): Mounting V5 Filesystem
388:[ 5.596968] XFS (sda2): Ending clean mount
389-[ 5.596980] xfs filesystem being mounted at /boot supports timestamps until 2038 (0x7fffffff)
390-[ 5.661137] fbcon: Taking over console
391-[ 5.661309] Console: switching to colour frame buffer device 144x54
392:[ 5.667166] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
393-[ 5.893920] RPC: Registered named UNIX socket transport module.
394-[ 5.893921] RPC: Registered udp transport module.
395-[ 5.893921] RPC: Registered tcp transport module.
dmesg显示内核信息
基础正则表达式练习
这里只描述一些特别的正则表达式.
练习文件: http://linux.vbird.org/linux_basic/0330regularex/regular_express.txt
- 利用中括号[]来查找集合字符
- 行首和行尾字符^$
- 任意一个字符.和任意字符*
- 限定连续RE字符范围{} (注意{}需要转义)
基础正则表达式字符集合
| RE | 意义与范例 |
|---|---|
| ^word | |
| word$ | |
| . | |
| \ | |
| * | |
| [list] | |
| [n1-n2] | |
| [^list] | |
| \{n,m\} |
sed工具
核心: sed可以使用正则表达式完成数据替换, 删除, 新增, 选择.
语法:
sed [-nefr] [操作]
选项与参数:
-i : 直接修改文件操作
-e : 适用于多个命令
-n : 不产生输出
操作:
n1,n2 function
function:
a 新增
c 替换
d 删除
i 插入
p 打印
s 替换
常用操作:
删除特定行
nl /etc/passwd | sed '2,5d'行后追加数据
nl /etc/passwd | sed '2a drink tea'行前插入数据
nl /etc/passwd | sed '2i drink tea'行替换数据
nl /etc/passwd | sed '2,5c No 2-5 Number'打印指定行数据
nl /etc/passwd | sed -n '2,5p'行部分数据替换
sed 's/替换字符/被替换/g'直接修改文件内容
sed -i 's/\.$/\!/g' file
扩展正则表达式
扩展正则表达式支持语法:
| RE | 含义 |
|---|---|
| + | 重复一个或以上字符 示例: egrep -n ‘go+d’ regulare_express.txt |
| ? | 0个或1一个字符 示例: egrep -n ‘go?d’ regulare_express.txt |
| | | 或者 范例: egreo -n ‘gd|good’ regulare_express.txt |
| () | 找出群组字符串 范例: egrep -n ‘g(la|oo)d’ regulare_express.txt |
| ()+ | 多个重复群组 范例: echo ‘AxyzxyzxyzC’ | egrep ‘A(xyz)+C’ |
文件的格式化与相关处理
格式化打印: printf
测试文件:
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
语法:
printf '打印格式' 实际内容
选项与参数:
\n :换行
\t : tab
\xNN : ASCII表示的字符
变量格式:
%ns : n为数字, s代表string, 即n个string
%ni : n个整数位数
%N.nf : N表示数据宽度, n表示小数位数, f代表浮点数
示例:
[root@kuaicdn tmp]# printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
[root@kuaicdn tmp]# printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt)
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
[root@kuaicdn tmp]# printf '\x45\n'
E
awk
核心: awk一般用于处理行的字段,通过分隔符将行分成字段进行分析.
这部分会单独做文档分析
语法:
awk '条件类型1{操作1} 条件类型2{操作2} ...' filename
示例:
[root@kuaicdn tmp]# last -n 5 | awk '{print $1"\t"$3}'
root 192.168.2.32
root 192.168.2.28
root 192.168.2.28
root 192.168.2.26
root 192.168.2.29
wtmp Sun
注意$0, $1…的作用
特殊变量:
- NF : 每一行的字段总数
- NR : awk处理的是第n行数据
- FS : 分隔符
示例:
[root@kuaicdn tmp]# last -n 5 | awk '{print NF "\t" NR "\t" FS}'
10 1
10 2
10 3
10 4
10 5
0 6
7 7
awk的逻辑运算符:
, < , >=, <=, ==, !=
示例:
[root@kuaicdn tmp]# awk -F: '$3<10{print $1 "\t" $3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
文件比对工具
场景: 文件新旧版本的比较
diff
核心: diff用于比对两个文件之间的差异, 以行单位进行比较.
语法:
diff [-bBi] from-file to-file
注意: from-file和to-file可以用-来代表标准输入
选项与参数:
示例1: 更新/etc/passwd文: 删除第4行, 第6行替换为no six line, 进行比较
[root@kuaicdn tmp]# mkdir -p /tmp/testpw
[root@kuaicdn tmp]# cd /tmp/testpw/
[root@kuaicdn testpw]# cp /etc/passwd passwd.old
[root@kuaicdn testpw]# cat /etc/passwd | sed -e '4d' -e '6c no six line' > passwd.new
[root@kuaicdn testpw]# diff passwd.old passwd.new
4d3
< adm:x:3:4:adm:/var/adm:/sbin/nologin
6c5
< sync:x:5:0:sync:/sbin:/bin/sync
---
> no six line
实例2: 可以用于比较目录内的文件的差异
[root@kuaicdn testpw]# diff /etc/rc0.d/ /etc/rc5.d/
只在 /etc/rc0.d/ 存在:K90network
只在 /etc/rc5.d/ 存在:S10network
cmp
核心: cmp主要用于字节的比较
[root@kuaicdn testpw]# cmp passwd.old passwd.new
passwd.old passwd.new 不同:第 106 字节,第 4 行
patch
核心: 可以使用diff命令获取旧文件和新文件的差异从而制作补丁, 可以使用patch补丁将旧文件更新为新文件或者恢复.
语法:
patch -pN < patch_file # 更新旧文件
patch -R -pN < patch_file #恢复旧文件
选项:
-p 代表目录层数
示例: 将passwd.old更新为passwd.new
[root@kuaicdn testpw]# diff -Naur passwd.old passwd.new > passwd.patch
[root@kuaicdn testpw]# cat -n passwd.patch
1 --- passwd.old 2021-11-09 14:11:52.861119127 +0800
2 +++ passwd.new 2021-11-09 14:12:34.373007050 +0800
3 @@ -1,9 +1,8 @@
4 root:x:0:0:root:/root:/bin/bash
5 bin:x:1:1:bin:/bin:/sbin/nologin
6 daemon:x:2:2:daemon:/sbin:/sbin/nologin
7 -adm:x:3:4:adm:/var/adm:/sbin/nologin
8 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
9 -sync:x:5:0:sync:/sbin:/bin/sync
10 +no six line
11 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
12 halt:x:7:0:halt:/sbin:/sbin/halt
13 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@kuaicdn testpw]# patch -p0 < passwd.patch
patching file passwd.old
[root@kuaicdn testpw]# ls
passwd.new passwd.old passwd.patch
[root@kuaicdn testpw]# diff passwd.old passwd.new
[root@kuaicdn testpw]# patch -R -p0 < passwd.patch
patching file passwd.old
[root@kuaicdn testpw]# diff passwd.old passwd.new
4d3
< adm:x:3:4:adm:/var/adm:/sbin/nologin
6c5
< sync:x:5:0:sync:/sbin:/bin/sync
---
> no six line
pr
核心: 给文件增添页码和也叫.
pr /etc/man_db.conf
重点
- 正则表达式与通配符是完全不一样的东西, 通配符代表的是bash的一个功能
- grep会其它正则表达式工具会受语系影响
- egrep支持扩展正则表达式
- 注意用[:digit:]特殊符号来代替字符串集合
