最近一段时间一直在学习算术运算和正则表达式以及条件判断,连续看了四五遍,基本概念已经能够搞清楚了,实际操作中容易把正则表达式和算术运算以及条件判断混淆.看来还是要勤加联系.今天终于是有勇气来总结这两周的学习.在这之前,因为在练习这些逻辑概念性的知识经常会用到grep命令.首先介绍一下grep.
格式:grep [options] 'PATTERN' file,...
grep: 文本搜索工具,根据用户指定的文本模式对目标文件进行逐行搜索,显示文件中能够被模式所匹配到的行.
模式PATTERN:指的是使用算术运算,正则表达式,或条件判断按组合成的字符串规则,按照这个规则在文件中查找是否有符合条件的行,简单来讲就是按照一定规则输出文件中匹配这个规则的内容.
#grep --color=auto Boot /etc/rc.d/rc.sysinit##显示/etc/rc.d/rc.sysinit文件中匹配Boot字符的行,匹配的字符选择以--color=auto选项的红色样式输出
grep 常用选项:
--color=auto:查找到的字符串显示颜色
-v: 反向,显示不能被模式所匹配到的行;(用在排除法)
#grep -v 'root' /etc/passwd #排除空白行后输出结果
-o: 仅显示被模式匹配到的字串,而非整行;
-i: 不区分字符大小写,ignore-case
-E: 支持扩展的正则表达式
正则表达式:是一类字符所书写出的模式(pattern),元字符不表示字符本身的意义,用于额外功能性的描述(类似文件名通配符).分为基本正则表达式和扩展正则表达式
基本正则表式的元字符:(grep -E支持扩展正则表达式)
字符匹配符:
.: 任意单个字符
[]: 指定范围内的任意单个字符:数字[0-9],[[:digit:]];字母[a-z],[[:lower:]];大写字母[A-Z],:upper:]];不区分大小写字母[[:alpha:]];数字和字母[[:alnum:]];空格[[:space:]];标点符号[[:punct:]]
[^]:指定范围外的任意单个字符:[^1-8]结果就为0,9
#grep --color=auto '[Rr]..[Tt]' /etc/passwd ##[Rr]起始中间任意两个字符[Tt]结尾
#grep --color=auto '[Rr].*[Tt]' /etc/passwd ##[Rr]起始中间任意个字符[Tt]结尾
#grep --color=auto '[Rr][^[:punct:]].[Tt]' /etc/passwd##[Rr]起始中间一个非符号字符和一个任意字符[Tt]结尾
*: 前面一个字符匹配任意次.例:x*y 匹配 xxy,xy,y,(*表示X可以出现任意次都匹配)
.*: 匹配任意长度的任意字符
\?: 匹配前一个字符0次或1次,
x\?y 匹配 xy,xxy
\{\}因为在正则表达式中,是尽可能长的去匹配字符;所以在特定匹配次数情况下要用{}.
\{m\}: 匹配m次
\{m,n\}:至少m次,至多n次
\{0,n\}:可以有可以没有至多n次;
位置锚定符:用于指定字符出现的位置
^: 锚定行首,在行首出现的字符,在字符左侧,以^开始为标识^Char (行首带Char的字符).
#grep --color=auto '^[Rr][^[:punct:]].[Tt]' /etc/passwd ##/etc/passwd文件中以大小写r开头跟一个非符号字符和一个任意字符以大小写t结束的四字字符串
$: 锚定行尾,在行尾出现的字符,在字符右侧,以$结束为标识,char$(行尾为Char结尾).
#grep --color=auto 'bash$' /etc/passwd ##以精确查找/etc/passwd文件an中bash结尾的行
^$: 空白行,行首和行尾之间没有任何字符.所以是空白行
#grep '^$' /etc/rc.d/rc.sysinit | wc -l ##查找rc.sysinit中的空白行并通过管道输出给wc命令统计行数
\<|\b:\<或者\b 锚定词首:查找以模式为词首的单词
#grep --color=auto '\<[Rr][^[:punct:]].[Tt]' /etc/passwd ##passwd中以[Rr]开头的单词
\>|\b:\>或者\b锚定词尾,查找以模式为词首的单词
\<***\>:锚定词首和词尾组合可以精确匹配单词,或精确字符序列
分组:多个字符的组合的模式:
\(\)
#\(ab\)*xy ##任意个ab带xy字符,xy前后字符一致 错误的是ab*xy只匹配a和任意个b带xy的字符
引用:对分组的字符进行位置参数进行引用
\1: 后向引用,引用模式中前面的第一个左括号以及与之对应的右括号中的模式所匹配到的内容
\2: 后向引用,引用模式中前面的第二个左括号以及与之对应的右括号中的模式所匹配到的内容
\(a.b\)xy\1: a6bxya6b,(\1前面匹配到什么后面也要引用什么 a6bxya7b就不匹配)
#匹配grep.txt中匹配字符两种不同方式的不同:
He like his lover.
She love her liker.
He love his lover.
She like her liker. ##保存到grep.sh
#grep --color=auto 'l..e.*l..er' grep.sh ## l..e都会匹配到,没有引用所以按字符匹配
#grep --color=auto '\(l..e\).*\1r' grep.sh ##love对lover,like对liker,有引用,所以前后字符会对引用内容精确匹配!
egrep: 和grep命令使用差不多,使用扩展正则表达来构建模式,相当于grep -E.这里就把不同的地方提出来
次数匹配:
?: 匹配其前面的字符0或1次;不用加\号
+: 匹配其前面的字符至少1次
{m}: 匹配其前面的字符m次;用法一样也是不用加\号
{m,n}: 至少m次,至多n次
{m,}: 至少m次;
{0,n}:至多n次;
锚定:
\<,\b: 词首单词的这两个还是要加\号
\>,\b:词尾
分组:
(): 分组,用法一样也是不用加\号
|: 或者,grep没有的功能 整串扩展选择,扩展的内容最好用(),不加括号是对|左右两侧的整个字符串进行选择
grep -E "con(C|c)at" ##结果为conCat或concat
grep -E "conC|cat" ##结果为conC或cat
PS:在grep和egre使用中在很多地方例如:(),{},<>,?等符号需要根据使用不同命令或选项,加或者不加\转译符,以示这里是做正则表达式的作用,不然会被系统认作其它意义的符号,一定要记清楚,经常出错都是在转译符的不当使用.
shell的算数运算:还是先来说一说常用的命令
declare:申明一个变量为整数并初始化变量. -i:整型变量 #declare -ivarName=0
let:执行算数表达式,结果必须保存在变量中!
let varName=算术表达式
例: #num1=4
#num2=7
#let sum=$num1+$num2
#let er=$num2/num1
varName=$[算术表达式] (可以获得结果,可以不用些let)
例: #mul=$[$num1*$num2] (不用写let)
varName=$((算术表达式))
算数操作符:
+加,-减,*,/,%取余,bash不能执行浮点运算,如果计算中存在小数,将会被圆整,小数部分会被丢弃!
+=,-=,*=,/=,%=:对自己进行运算并赋值给自己,如果一个变量的数值取出之后就不再使用,只需要保存计算后的值,可以将计算后数值又保存回这个变量可以节省内存.
#totalweight=40
#totalweight=$[$totalweight+2] ##把变量totalweight加2在赋值给这个变量,表达式本身就是进行运算后再赋值给自己,所以可以不用申明
#let totalweight+=2 ##totalweight+=2本身不是变量赋值,所以需要let申明运算后赋值给自身.
++ -- 自加1自减1
#let totalweight++ ##先引用变量再计算
#let ++totalweight ##先计算在引用变量
相比较来说算术运算和正则表达式是比较枯燥的内容,而且需要不断练习去理解每种结构的逻辑才能保证不会错误书写错误,本来想把条件测试的内容写到一起,发现条件判断内容也是非常的多,所以还是放到下一篇博客来专门写!这些内容在书写格式上和逻辑要有许多相近的地方特别容易搞错,多花些心思.勤练习,不放弃!每次能够写一个小小的脚本也是很有成就感的.
最后还是在博客的最后放一些练习题,看一次练一次.熟能生巧!
练习:计算100以内所有正整数之和
练习:分别计算100以内所有偶数之和和奇数之和;
练习:计算/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/issue三个文件的字符数之和;
练习:计算当前系统所有用户的ID之和;
练习:新建用户tmpuser1-tmpuser10,并计算他们的id之和;
练习: 写一个脚本,用键盘随意输入两个数,计算两者和商积差.
练习:通过键盘给定一个目录路径,默认为/,来判断目录下文件内容的类型;
练习:显示/proc/meminfo文件中以大小写s开头的行;
练习:取出默认shell为非bash的用户;
练习:取出默认shell为bash的且其ID号最大的用户;
练习:显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
练习:显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
练习:找出/etc/passwd文件中一位数或两位数;
练习:找出ifconfig命令结果中的1到255之间的整数;
练习:查看当前系统上root用户的所有信息;
练习:添加用户bash和testbash、basher,而后找出当前系统上其用户名和默认shell相同的用户;
练习:找出netstat -tan命令执行的结果中以“LISTEN”或“ESTABLISHED”结尾的行;
练习:取出当前系统上所有用户的shell,要求:每种shell只显示一次,且按升序显示;
练习:写一个脚本,分别统计/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件中各自以#开头的行的行数,以及空白行的行数;
练习:写一个脚本,分别复制/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件至/tmp目录中,文件名为原名后跟上当前的日期组成;
例如第一个文件复制后的名称为/tmp/rc.sysinit-2-14-02-16;
练习:写一个脚本显示当前系统上所有默认shell为bash的用户的用户名、UID以及其在/etc/passwd文件中的行号;