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

示例:

  1. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alnum:]]
  2. 12314ADAvada?/
  3. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep "[:alnum:]"
  4. grep: character class syntax is [[:space:]], not [:space:]
  5. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alnum:]]
  6. 12314ADAvada?/
  7. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:alpha:]]
  8. 12314ADAvada?/
  9. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:upper:]]
  10. 12314ADAvada?/
  11. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:lower:]]
  12. 12314ADAvada?/
  13. [root@kuaicdn tmp]# echo "12314ADAvada?/" | grep [[:digit:]]
  14. 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:]特殊符号来代替字符串集合