热身
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
例如 grep, expr, sed , awk. 或Vi中经常会使用到正则表达式,为了充分发挥 shell 编程的威力,需要精通正则表达式。
下面先举个简单例子来让大家对正则表达式有个直观的感受。ls命令是linux下最常用的命令。ls命令是list的缩写,缺省下ls用来打印出当前目录的清单。
现在,我们只希望列出以d开头的文件或目录,可以用ls d* 命令,这里*就是正则表达式,它表示匹配重复零次或多次前一字符。
举一反三,列出以che 开头的文件或目录,就可以用ls che* 命令。
是不是觉得有些觉得过于简单了啊??!!好吧,打完小怪,现在升下级。
开始……
如何列出当前目录下的所有目录(不包含下面的子目录)?
思考……
又到了使出正则表达式杀手锏的时候了,在这里,我们还是使用ls 命令,但是加了个 -l选项(-l选项作用是列出文件的详细信息),使用正则表达式列出当前目录下的所有目录,我们给出了两种方法(聪明的你当然会想到也可以用find命令,呵呵,这属于第三种秘笈了)。且看:
这样列出来的内容有些多,没完全截下来所有显示结果,但这并不妨碍本文的讲解。
考虑到普通文件是以-开头,如dataf1.txt文件;目录是以d 开头的,如 adv_shell 是目录,即第一个字母会不小心暴露出文件的身份属性。
所以我们就从d这里作为突破口,这时,你会想到,有多少个“开头”的d就应该有多少个目录,太聪明了,好吧,我们按照你的思路实践下。
现在,问题出来了,怎么统计出来有多少个“开头”的d?你想到了linux中grep命令,还想到了正则表达式,于是grep和正则表达式开始粉墨登场了……
ls -l |grep "^d"
这条简单的命令就轻松解决了我们的问题,。"^d"???你纳闷了,这个小东西配合起来怎么会有那么大的威力呢?这好比玩三国杀时刘备、司马懿、香香之间配合的威力……"^d",就是正则表达式的用法,"^"表示匹配行首,"^d"合起来就表示以d开头的一行,grep "^d" 就是过滤出以d开头的那些行,d 表示目录,也就过滤出了当前目录中的所有目录。
谜底解开。现在你又想到,前面不是说还有一种方法的么,既然如此迫不及待,那就只好顺水推舟了。
第二种方法还是基于ls命令,但是用了-F 选项,-F 选项能列出文件类型的指示符号,如下图所示:
仔细观察我们发现,在文件名后面,会多出了一些符号,如目录adv_shell名字后多了条斜扛(/),可执行文件checkhost.sh名字后多了个星号(*)……在此,如果想更多了解这些符号意义,可以查看ls 命令的详细信息。
我们现在把注意力集中到目录adv_shell名字后多了条斜扛(/)这条信息上。很快联想到,有多少个斜扛(/)就应该对应多少目录,而且斜扛(/)会跟在每个目录名的最后。我们又想到了grep命令,还想到了应该怎样用正则表达式表示出匹配行尾,答案已经很接近了……
ls -F | grep "/$"
这条短命令又一切成全了我们的梦想。"/$" 也是正则表达式的用法,"$"表示匹配行首,"/$"合起来就表示匹配以/结尾的行,grep "/$" 就是过滤出以/结尾的那些行,/表示目录,也就过滤出了当前目录中的所有目录。
在此基础上,我们发散一下思维,比如说想统计当前目录下的文件个数及目录个数,就可以使用以下命令:
ls -l * |grep "^-"|wc -l
ls -l * |grep "^d"|wc -l
好了,暂且休息,下面我们开始介绍更多关于正则表达式的知识。
蓄势
前面我们初识了^ $ * 这些个正则表达式的用法,下面我们将进行更高一级的升炼。
正则表达式是一个字符或和元字符组合成的字符集,它们匹配(或指定)一个模式。字符即普通字符(例如字符 a 到 z),元字符即特殊字符(例如前面提到的字符 ^ $ *)。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
在这里,为简单见,我们不会介绍所有的正则表达式知识,只介绍常用的一些正则表达式知识。
一个正则表达式包含下面一个或多个项:
1.一个字符集
这里的字符集里的字符表示的就是它们字面上的意思.正则表达式最简单的情况就是仅仅由字符集组成,而没有其他的元字符。
2.锚
一个锚指明了正则表达式在一行文本中要匹配的位置,例如^和$就是锚。
3.修饰符
它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围.修饰符包括了星号、括号和反斜杠符号。
* 匹配重复零次或多次前一字符
+ 匹配一个或多个前面的字符.它的作用和*很相似,但唯一的区别是它不匹配零个字 符的情况
? 匹配零或一个前面的字符。它一般用于匹配单个字符
. 匹配任意字符( 除换行符 )
^ 匹配一行的开头,但依赖于上下文环境,可能在正则表达式中表示否定一个字符 集的意思
[...] 匹配集合中任意字符 如"[xyz]" 匹配字符 x, y, 或z
[^...] 匹配不属集合 中 任意字符
^, $ 匹配 行首、行尾
\<, \> 用于表示单词的边界。\< 匹配词首,\>词尾,如"\<the\>" 匹配单词"the"
\(...\) 正则表达式分组。进行子字符串提取(substring extraction)一起使用很有用
\n 第 n 个分组内容
\ 转义(escapes) 一个特殊的字符,使这个字符表示原来字面上的意思。"\$"表示 了原来的字面意思"$",而不是在正则表达式中表达的匹配行尾的意思."\\"也被 解释成了字面上的意思"\"
\{ \} 指示前面正则表达式匹配的次数.
要转义是因为不转义的话大括号只是表示他们字面上的意思.这个用法只是技巧上 的而不是基本正则表达式的内容."[0-9]\{5\}" 精确匹配5个数字(从0到9的数字).
| "或",正则操作符用于匹配一组可选的字符
{n} n是一个非负整数。匹配确定的n次。例如,''o{2}'' 不能匹配 "Bob"中的''o'',但是能匹配"food" 中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,''o{2,}'' 不能匹配"Bob"中的'o'',但能匹配 "foooood"中的所有o。''o{1,}''等价于''o+''。''o{0,}''则等价于''o*''。
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,"o{1,3}"将匹配 "fooooood"中的前三个o。''o{0,1}''等价于''o?''。请注意在逗号和两个数之间不能有空格。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如,''er\b'' 可以匹配"never" 中的''er'',但不能匹配 "verb"中的 ''er''。
\B 匹配非单词边界。''er\B''能匹配"verb"中的''er'',但不能匹配"never"中的 ''er''
\w 匹配包括下划线的任何单词字符。等价于''[A-Za-z0-9_]''。
\W 匹配任何非单词字符。等价于''[^A-Za-z0-9_]''。
\d 匹配一个数字字符。等价于[0-9]。
\D 匹配一个非数字字符。等价于[^0-9]。
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。
\S 匹配任何非空白字符。等价于[^\f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09 和 \cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
常用的就介绍到这里,其它的需要进一步了解可以查阅手册或资料。
翱翔
部分例子
/\b([a-z]+)\1\b/gi 一个单词连续出现的位置
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ 将一个URL解析为协议、域、端口及相对路径
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/定位章节的位置
/[-a-z]/ A至z共26个字母再加一个-号。
/ter\b/ 可匹配chapter,而不能terminal
/\Bapt/ 可匹配chapter,而不能aptitude
/Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次的检索匹配。
下面来些更加高级些的例子。
对于vi 中命令的分析
s/\(^.*$\)\n^.*$/\1/g
初一看,会傻眼,眼前感觉全是$^.*/\……这些符号的闪动。
不要紧,下面慢慢道来。
先给出vi中替换命令的格式。
s/re/string 用string替换正则表达式re
如果在后面加了个g 如: s/re/string/g
表示表示对该行内符合模式的进行全部替换。
例如,s/\//_/g 这个正则表达式就表示,对行内所有的斜扛(/)替成下划线(_),\ /即替换命令格式中的re,用反斜扛\是为了转义,\ /即表示 / 的本意;_即替换命令格式中的string。
好了,了解vi中替换命令的格式后,我们再对细节进行分析。
前面介绍到 \(...\) 表示正则表达式分组,\n表示第 n 个分组内容,于是对于
s/\(^.*$\)\n^.*$/\1/g
中的 \1 ,就表示第一个正则表达式分组即\(^.*$\),我们暂将第一个正则表达式分组\(^.*$\)其记为:A
类推,\2就应该表示第二个正则表达式分组,即 \n^.*$ 实际上 也应该写在括号内比较好:\(\n^.*$\) ,我们也暂将第二个正则表达式分组 \n^.*$ 记为:B
好了,
%s/\(^.*$\)\n^.*$/\1/g
就可以写为:
s/AB/A/g
作用就是将行内所有的AB都替换成A。
现在我们来分别分析A和B的作用。
A=\(^.*$\)
抽取出来实际上是\(...\),表示正则表达式 分组,再分析括号内的^.*$,^代表行首,点号(.)匹配任意字符(除换行符),星号(*)匹配重复零次或多次前一字符,$代表匹配到行尾,综合起来就是:匹配这一行
B=\n^.*$
分析: \n换行,^.*$同上,表示匹配这一行,综合起来就是:下一行(即上行结束后开始的另一行)。
再于是就有:%s/AB/A/g 即将所有AB都替换成B ,代入A和B各自意思得到:
将两行(如行1和行2 )内容替换为第一行内容(即行1的内容),加上/g,就是对全文进行前述替换,也就是隔行删除,如果是从文件第一行开始进行的操作,就意味着是删除所有偶数行、保留所有奇数行操作。
从上面的分析过程中,我们总结出两条有用的正则表达式:
%s/\(^.*$\)\n^.*$/\1/g 删除偶数行
%s/^.*$\n\(^.*$\)/\1/g 删除奇数行
不过瘾的话,还可以再看看另一例子:
sed 's/\(.*\)\(.\)$/\2/'
\2就应该表示第二个正则表达式分组
同上,也将A=/\(.*\),B=\(.\)$,表达式变为's/AB/B',将AB都替换成B 。
分析A、B作用。
A=/\(.*\)
抽取出来实际上是\(...\),表示正则表达式 分组,再分析括号内的 .*,表示匹配任意零个或多个字符 ( 除换行符 )
B=\(.\)$
括号内的 . ,表示匹配任意字符(除换行符) ,括号外的$表示匹配到行尾,即表示行尾的最后一个字符;那上述的A /\(.*\) 就表示该行最后一个字符前的所有字符。
于是sed 's/\(.*\)\(.\)$/\2/' 作用就是:删除该行除最后一个字符外的所有字符,保留最后一个字符,也即取得该行最后一个字符。
好了,正则表达式的介绍就告一段落,知识点比较多,需要平时反复的积累,遇到复杂的正则表达式时首先要克服恐惧的心理,然后按照上面的方法化繁为简,抓住其本质的东西,有如探囊取物,必手到擒来。
shell命令执行的相应顺序
&&
命令1 && 命令2 如果这个命令1执行成功 && 那么执行这个命2
mv myfile myfile2 && echo "if you are seeing this then mv was success!"
||
如果||左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2)
mv myfile myfile2 && echo "if you are seeing this then mv was success! "
从一个审计文件中抽取第1个和第2个域,并将其输出到一个临时文件中,如果这一操作未成功,我希望能够收到一个相应邮件:
awk '{print$1,$2}' test3 >test2 || echo "sorry the extraction didn't work " | mail root
(命令1;命令2;. . .)
如果使用{ }来代替(),那么相应的命令将在子s h e l l而不是当前s h e l l中作为一个整体被执行,只有在{ }中所有命令的输出作为一个整体被重定向时,其中的命令才被放到子s h e l l中执行,否则在当前s h e l l执行。
例子:
如果s o r t命令执行成功了,可以先将输出文件备份,然后再打印
test.sorted && (cp test.sorted test.sorted_bak ;lp test.sorted)
经常使用的正则表达式举例
^ 行首
$ 行尾
^ [ t h e ] 以t h e开头行
[ S s ] i g n a [ l L ] 匹配单词s i g n a l、s i g n a L、S i g n a l、S i g n a L
[Ss]igna[lL]". 同上,但加一句点
[ m a y M A Y ] 包含m a y大写或小写字母的行
^ U S E R $ 只包含U S E R的行
[tty]$ 以t t y结尾的行
" . 带句点的行
^ d . . x . . x . . x 对用户、用户组及其他用户组成员有可执行权限的目录
^ [ ^ l ] 排除关联目录的目录列表
^[^d] ls –l | grep ^[^d] 只显示非文件夹的文件
[ . * 0 ] 0之前或之后加任意字符
[ 0 0 0 * ] 0 0 0或更多个
[ iI] 大写或小写I
[ i I ] [ n N ] 大写或小写i或n
[ ^ $ ] 空行
[ ^ . * $ ] 匹配行中任意字符串
^ . . . . . . $ 包括6个字符的行
[a- zA-Z] 任意单字符
[ a - z ] [ a - z ] * 至少一个小写字母
[ ^ 0 - 9 " $ ] 非数字或美元标识
[ ^ 0 - 0 A - Z a - z ] 非数字或字母
[ 1 2 3 ] 1到3中一个数字
[ D d ] e v i c e 单词d e v i c e或D e v i c e
D e . . c e 前两个字母为D e,后跟两个任意字符,最后为c e
" ^ q 以^ q开始行
^ . $ 仅有一个字符的行
^".[0-9][0-9] 以一个句点和两个数字开始的行
' " D e v i c e " ' 单词d e v i c e
D e [ V v ] i c e " . 单词D e v i c e或d e v i c e
[ 0 - 9 ] " { 2 " } - [ 0 - 9 ] " { 2 " } - [ 0 - 9 ] " { 4 " } 对日期格式d d - m m - y y y y
[ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } " . [ 0 - 9 ] " { 3 " } I P地址格式
[ ^ . * $ ] 匹配任意行
[A-Za-z]* 匹配所有单词
常用的g r e p选项
-c 只输出匹配行的计数。
-i 不区分大小写(只适用于单字符)。
-h 查询多文件时不显示文件名。
-l 查询多文件时只输出包含匹配字符的文件名。
-n 显示匹配行及行号。
-s 不显示不存在或无匹配文本的错误信息。
-v 显示不包含匹配文本的所有行。
例子
grep -v "Sort" tab2 显示不包含匹配文本的所有行
grep -n "Sort" tab2 显示匹配行及行号
grep -c "Sort" tab2 只输出匹配行的计数
精确匹配: grep "01">" tab2
grep -in "code" tab2 忽略大小写
多次过滤
grep -in "code" tab2 | grep "02"
使用grep匹配“与”或者“或”模式
g r e p命令加- E参数,这一扩展允许使用扩展模式匹配。例如,要抽取城市代码为2 1 9或2 1 6,方法如下:
grep –E ‘219|216’ tab2
g r e p允许使用国际字符模式匹配或匹配模式的类名形式。
类 等价的正则表达式
[ [ : u p p e r : ] ] [ A - Z ]
[ [ : a l n u m : ] ] [ 0 - 9 a - zA-Z]
[ [ : l o w e r : ] ] [ a - z ]
[ [ : s p a c e : ] ] 空格或t a b键
[ [ : d i g i t : ] ] [ 0 - 9 ]
[ [ : a l p h a : ] ] [ a - z A - Z ]
大多数系统管理员称 / d e v / n u l l为比特池, 可以将之看成一个无底洞,有进没有出,永远也不会填满。
要查看D N S服务器是否正在运行(通常称为n a m e d),方法如下
ps -ef | grep "name"|grep -v "grep"
(2)
相关推荐
虚拟机vmware workstatiions pro 17.6.1个人使用免费,不用证书直接安装使用
scipy-1.2.0-cp35-cp35m-linux_armv7l.whl
基于springboot爬虫高考志愿智能推荐系统源码数据库文档.zip
bimdata_api_client-4.3.0-py3-none-any.whl
Pillow-7.0.0-cp37-cp37m-linux_armv7l.whl
onnxruntime-1.16.2-cp38-cp38-win_amd64.whl
opencv_python-4.4.0.46-cp39-cp39-linux_armv7l.whl
论文描述:该论文研究了某一特定领域的问题,并提出了新的解决方案。论文首先对问题进行了详细的分析和理解,并对已有的研究成果进行了综述。然后,论文提出了一种全新的解决方案,包括算法、模型或方法。在整个研究过程中,论文使用了合适的实验设计和数据集,并进行了充分的实验验证。最后,论文对解决方案的性能进行了全面的评估和分析,并提出了进一步的研究方向。 源码内容描述:该源码实现了论文中提出的新的解决方案。源码中包含了算法、模型或方法的具体实现代码,以及相关的数据预处理、实验设计和性能评估代码。源码中还包括了合适的注释和文档,以方便其他研究者理解和使用。源码的实现应该具有可读性、可维护性和高效性,并能够复现论文中的实验结果。此外,源码还应该尽可能具有通用性,以便在其他类似问题上进行进一步的应用和扩展。
ta_lib-0.5.1-cp313-cp313-win32.whl
STM32开发相关软件ISP 程序下载STM32开发相关软件ISP 程序下载提取方式是百度网盘分享地址
java源码资源基于JAVA的UDP服务器模型源代码提取方式是百度网盘分享地址
基于Python+Django的电影票房数据分析系统源码数据库文档.zip
onnxruntime-1.19.0-cp311-cp311-win_amd64.whl
Java固定资产管理系统源码 固定资产管理系统是对高校固定资产的一个信息化管理系统,基本功能包括:对固定资产的购进、接触、销毁,对物品的使用状态、借出状态、库存状态等进行标识,对各类物品进行编号,根据编号进行查询,根据名称进行查询等。本系统结构如下: (1)系统登录:用户登录模块:登录功能 重置 (2)系统用户管理:对系统用户的增加 系统用户的权限修改 系统用户的删除 分配系统用户的权限 修改本身登录密码 资产的相关维护 (3)员工信息管理:教工的增加、修改、删除、查询 (4)资产入库管理:资产的属性修改 资产的报废删除 资产的属性查询 (5)资产维护管理:物资的维修、维护物资的信息修改 (6)资产借还管理:增加借出资产 查询借出资产 归还已借出资产(7)打印报表
matplotlib-3.7.0-cp311-cp311-linux_armv7l.whl
基于springboot的房屋租赁管理系统源码数据库文档.zip
opencv_contrib_python-4.1.0.25-cp35-cp35m-linux_armv7l.whl
bimdata_api_client-3.1.0-py3-none-any.whl
本23级物流01班谭敏20234970114.docx
opencv_contrib_python-4.5.2.52-cp39-cp39-linux_armv7l.whl