【shell笔记>实战】正则表达式实战

这里演示shell脚本中常见的一些正则表达式例子。如果你对正则表达式不理解,先阅读学习正则表达式一文。

目录文件计数

让我们尝试一下对PATH环境变量中定义的目录里的可执行文件进行计数。

首先我们得将PATH变量解析成单独的目录名。

$ echo $PATH
/home/wsx/bin:/home/wsx/anaconda3/bin::/home/wsx/bin:/home/wsx/anaconda3/bin:/home/wsx/bin:/usr/local/sbin:/usr/local/bin:/usr/
sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/wsx/.fzf/bin

你的PATH环境变量可能会不同,但要意识到PATH中的每个路径由冒号分隔。所以我们先要用空格替换冒号得到目录列表。

$ echo $PATH | sed 's/:/ /g'
/home/wsx/bin /home/wsx/anaconda3/bin  /home/wsx/bin /home/wsx/anaconda3/bin /home/wsx/bin /usr/local/sbin /usr/local/bin /usr/
sbin /usr/bin /sbin /bin /usr/games /usr/local/games /snap/bin /home/wsx/.fzf/bin

分离目录后,我们可以使用标准的for语句来遍历目录。

mypath=$(echo $PATH | sed 's/:/ /g')
for directory in $mypath
do
...
done

一旦获得了单个目录,就可以使用ls命令来列出每个目录中的文件,并用另一个for语句来遍历每个文件,为文件计数器增值。

脚本最终版如下:

wsx@wsx:~/tmp$ cat countfiles
#!/bin/bash
# count number of files in your PATH
mypath=$(echo $PATH | sed 's/:/ /g')
count=0
for directory in $mypath
do
    check=$(ls $directory)
    for item in $check
    do
        count=$[ $count + 1 ]
    done
    echo "$directory - $count"
    count=0
done
wsx@wsx:~/tmp$ ./countfiles
/home/wsx/anaconda3/bin - 356
/home/wsx/bin - 75
/usr/local/sbin - 0
/usr/local/bin - 17
/usr/sbin - 214
/usr/bin - 2260
/sbin - 176
/bin - 162
/usr/games - 5
/usr/local/games - 0

解析邮件地址

邮件地址的基本格式为:

username@hostname

username值可以用字母数字字符以及以下特殊字符:

  • 点号
  • 单破折号
  • 加号
  • 下划线

邮件地址hostname部分由一个或多个域名和一个服务器组成。服务器名和域名也必须遵照严格的命名规则,只允许字母数字字符以及以下的特殊字符:

  • 点号
  • 下划线

服务器名和域名都用点号分隔,先指定服务器名,紧接着指定子域名,最后是后面不带点号的顶级域名。

顶级域名的数量在过去十分有限,正则表达式模式编写者会尝试将它们加到验证模式中。然而遗憾的是,现在顶级域名也增多了,这种方法已经不可行。

从左侧开始构建这个正则表达式模式。用户名可以有多个有效字符,这个相当容易。

^([a-zA-Z0-9_\-\.\+]+)@

这个分组指定了用户名中允许的字符,加号表明至少有一个字符。下一个字符是@,没有什么好惊讶的。

hostname模式使用同样的方法来匹配服务器名和子域名。

([a-zA-Z0-9_\-\.\+]+)

这个模式可以匹配文本。

server
server.subdomain
server.subdomain.subdomain

对于顶级域名,有一些特殊的规则。顶级域名只能是字母字符,必须不少于二个字符(国家或地区代码中使用),并且在长度上不得超过五个字符。下面就是顶级域名用的正则表达式模式。

\.([a-zA-Z]{2,5})$

将整个模式放在一起会生成如下模式。

^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.\+]+)\.([a-zA-Z]{2,5})$

这个模式会从数据列表中过滤掉那些格式不正确的邮件地址。现在可以创建脚本来实现检测邮件地址的功能了。

wsx@wsx:~/tmp$ echo "[email protected]" | ./isemail
[email protected]
wsx@wsx:~/tmp$ echo "[email protected]." | ./isemail
wsx@wsx:~/tmp$ echo "[email protected]" | ./isemail
wsx@wsx:~/tmp$ echo "rich@here-now" | ./isemail
wsx@wsx:~/tmp$ echo "[email protected]" | ./isemail
[email protected]
wsx@wsx:~/tmp$ echo "rich#[email protected]" | ./isemail

脚本比较粗糙,内容为:

#!/bin/bash

gawk --re-interval '/^[a-zA-Z0-9_\-\.\+]+@[a-zA-Z0-9_\-\.\+]+\.[a-zA-Z]{2,5}$/'

你可能感兴趣的:(【shell笔记>实战】正则表达式实战)