grep:文本处理三剑客中重要一员:grp ,sed ,awk
grep:文本过滤工具(基于模式:pattern实现过滤)
grep,egrep,fgrep
sed:strean editer ,文本编辑工具
awk:Linux上的实现为gawk,文本报告生成器
grep:global search regular expression and print out the line
作用:文本搜索工具,根据用户指定的‘模式’对目标文本逐行进行匹配检查,打印匹配到的行
模式:有正则表达式字符及文本字符所编写的过滤条件
regexp:正则表达式:由一类特殊字符及文本字符所编写的模式,其中有些字符不表示字面意义而表示控制或者通配
正则表达式分两类:
grep默认仅支持基本正则表达式,要使用扩展正则表达式要使用egrep或者grep -E
fgrep:fast grep 快速grep也可以用grep -F
正则表达式引擎
grep [OPTIONS] PATTERN [FILE...]
选项:
--color=auto 对匹配到的文本着色高亮显示
-v 反向选择,显示不能被pattern匹配的行
-i 匹配时忽略字符大小写
-o 仅显示匹配到的字符串
-q 静默模式
-A # 显示匹配行以及后#行
-B # 显示匹配行以及前#行
-C # 显示匹配行前后各#行
基本正则表达式元字符:(字符不表示字面意义,而表示通配或者控制)
字符匹配:
.: 匹配任意单个字符
[ ]: 匹配指定范围内的单个字符
[^]: 匹配指定范围 外的任意单个字符
[:alnum:]数字+字母 [:alpha:]大小写字母 [:blank:] [:cntrl:]
[:digit:]数字 [:graph:] [:lower:]小写字母 [:print:]
[:punct:]标点符号 [:space:]空格 [:upper:]大写字母 [:xdigit:]
匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数:
*:(仅表示次数,不同于glob)匹配前面的字符任意次,包括0次。
例如:grep “x*y” 可以匹配abxy,xay,xxxy
贪婪模式:默认贪婪,匹配所有符合项。xxxxxxxxy全匹配
.*:任意长度任意字符
\?:匹配\前面的字符0次或1次。即前面的字符可有可无
\+:匹配\前面字符至少一次
\{n\}:匹配\前面字符n次
\{m,n\}:匹配\前面字符m到n次
位置锚定:
^:行首锚定:用于模式最左侧
$:行尾锚定:用于模式最右侧
^PATTERN$:模式要能匹配整行信息
^$:空行 ^[[:space:]]*$:行首尾空格大于等于0
\< 或 \b:单词词首锚定,用于单词左侧
\> 或 \b:单词词尾锚定,用于单词右侧
\
分组符号:\(\):将一个或者多个字符捆绑在一起,当作一个整体进行处理
\(xy\)*ab:即锚定xy为单位出现n次
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1 , \2 , \3 等等
\1:表示从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符:
如:\(ab\+\(xy\)*\)
\1:引用ab\+\(xy\)*
\2:引用xy
后向引用:引用前面的分组括号中的模式所匹配字符,(而非模式本身)
练习:
显示/proc/meminfo文件中以大小s开头的行(使用两种方式)
显示/etc/passwd文件中不以bin/bash结尾的行
显示/etc/passwd文件中ID号最大的用户的用户名
如果用户root存在,显示其默认的shall程序
找出/etc/passwd 中的两位或者三位数
找出/etc/rc.d/rc.sysinit文件中,至少以一个空白字符开头且后面存在非空白字符的行
?
找出“netstat -tan”命令的结果中以”LISTEN”后跟数个空白字符结尾的行
添加用户bash、testbash、basher以及nologin(其shell为/sbin/nologin):而后找出/etc/passwd文件中用户名同shell名行。
[root@centos6 ~]# grep --color=auto '^\(\<[[:alnum:]]\+\>\).*\1$' /etc/passwd
^\(\<[[:alnum:]]\+\>\).*\1$ ——数字+字母
^\(\<[[:alnum:]]\+\>\).*\1$ ——一个或一个以上的(数字+字母)
^\(\<[[:alnum:]]\+\>\).*\1$ ——单词首尾锚定
^\(\<[[:alnum:]]\+\>\).*\1$ ——分组
^\(\<[[:alnum:]]\+\>\).*\1$ ——中间跟任意字符
^\(\<[[:alnum:]]\+\>\).*\1$ ——行首锚定
^\(\<[[:alnum:]]\+\>\).*\1$ ——(后向引用)行尾匹配\<[[:alnum:]]\+\>内容
写一个脚本,实现如下功能:
如果用户user1存在,则显示存在。否则添加用户。并显示添加用户的ID等信息
写脚本:
若有root登录则显示其登录,否则显示其未登录。
egrep:扩展正则表达式
egrep = grep -E
扩展正则表达式的元字符:
字符匹配:. [ ] [^]
次数匹配:* 匹配任意次 ?匹配0或1次 + 匹配一次或多次
{m} 匹配m次 {m,n} 匹配m到n次
锚定:
行:^ & 词: \< \b \> \b
分组:()
向后引用:\1 \2 ……
或者:a|b C|cat:C或cat (C|c)at:Cat或者cat
练习:
再,使用egrep 取出路径的目录名:
fgrep
不支持正则表达式,仅仅匹配给定字符串。所以快速。
bash 的基础特性
变量类型(决定):数据的存储格式、存储空间大小、参与运算种类
字符型;数值型(整型、浮点型)
强类型:定义变量时必须指定类型、参与运算必须符合类型要求
弱类型:无须指定类型。默认均为字符型:参与运算会自动进行隐式类型转换
bash是弱类型
bash中的变量的种类:
根据变量的生效范围等标准划分为:
本地变量:生效范围为当前shell进程。对其他shell和当前shell的子进程、父进程均无效
环境变量:生效范围为当前shell及其子进程。对其他shell无效
局部变量:生效范围为当前shell进程中某代码片段(通常指函数上下文)
位置变量:$1,$2……来表示,用于让脚本在脚本代码中调用通过命令行传递给他的参数
特殊变量:$?,$0,$#,$*,$@,
本地变量:
变量赋值:name=”VALUE”
可以使用引用:
VALUE:
变量引用:${name},$name
“ ”:弱引用,其中的变量会被替换为变量值
‘ ’:强引用,其中的变量不会被替换为变量值,而保持原字符串
显示已定义的所有变量:set
销毁变量:unset name
环境变量:
变量声明、赋值:
export name=VALUE
declare -x name=VALUE 等同先name=VALUE再加 declare -x name
变量引用:$name,$(name)
显示所有环境变量:export,env,printenv
撤销变量:unset name
bash有许多内建的环境变量:PATH,SHELL,UID,HISTSIZE,HOME,PWD,OLD,
HISTFILE,PS1
变量命名法则:
只读变量readonly name :
declare -r name
位置变量:在脚本代码中通过命令行传递给脚本的参数
$1,$2……:对应调用第1,第2等参数;
$0:调用命令本身
$*:传递给脚本的所有参数:所有参数当成一个字符串
$@:传递给脚本的所有参数:每个参数一个独立字符串
$#:传递给脚本的参数的个数:
换岗,剔除 shift [n]
示例:判断路径文件行数:
bash的配置文件
按生效范围划分两类:
/etc/profile
当配置文件过大,可拆分为多个配置文件/etc/profile.d/*.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
按功能划分,存在两类:
全局:/etc/profile,/etc/profile.d/*.sh
个人:~/.bash_profile
profile功用:
shell登录的类别:
直接通过终端,输入账号密码登录
使用:”su - username”或者”su -l username”切换登录的用户
文件读取顺序/etc/profile —》/etc/profile.d/*.sh —》~/.bash_profile —》~/.bashrc —》/etc/bashrc
注意:同一个变量在多个配置文件中赋值,以最后读取的配置文件为准
su username
图形界面下打开的终端(伪终端)
执行脚本
文件读取顺序:~/.bashrc —》/etc/bashrc —》/etc/profile.d/*.sh
问题:
定义在/etc/bashrc中
定义在/etc/profile.d/*.sh中
以上仅对当前shell有效
永久更改所有用户或者管理员$PATH: /etc/profile.d/*.sh和~/.bash_profile
新配置文件的生效方式:
bash中的算数运算:加+ 减- 乘* 除/ 取模(余数)% 次方**
帮助:help let
实现算数运算:
参数1:被操作数 参数2:运算符 参数3:操作数
注意:乘法符号*在bash的命令引用中表示通配,在某些运算中需要\转义。而在var=$[算数运算表达式]和var=$((算数表达式))中则不需要转义
bash内建的随机数生成器:$RANDOM——可以生成1-32767之间的随机数
如下:通过对随机数取模,生成1-60之间的随机数
判断随机生成的偶数还是奇数
变量取出运算后再赋值原变量:
# a=$[$a+1]等同于# let a+=1
# let a+=1增强型赋值:意为取出a的原值,加上1,再存回a
其他增强型赋值:
+=,-=,*=,/=,%=……
若加法每次都是+1,则也可使用# let a++
自增,自减运算:
let var+=1 同let var++
let var-=1 同 let var--
练习:
2、写一个脚本,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
3、脚本:统计/etc,/var,/usr目录共有多少个一级子目录和文件
条件测试:
判断某场景、需求是否满足,需要由测试机制来实现。
专用的测试表达式需要由测试命令辅助完成测试过程
测试命令:
注:表达式前后必须要有空格,否则为语法错误
bash的测试类型
-gt:是否大于
-ge:是否大于等于
-eq:是否等于
-ne:是否不等于
-lt:是否小于
-le:是否小于等于
==或=:等值测试
>:是否大于
<:是否小于
!=:是否不等于
=~:左侧的字符串是否能够被右侧的模式所匹配
注:=~表达式一般需要[[ 表达式 ]]格式
-z “字串或者变量”:测试字串是否为空,空则为真
-n “字串或者变量”: 测试字串是否不空,不空则为真
-a file /-e file :文件存在性测试,存在为真 否则为假
-b file :存在且为块设备
True if file exists and is a block special file.
-c file :存在且为字符设备文件
True if file exists and is a character special file.
-d file :存在且为目录文件
True if file exists and is a directory.
-f file :存在且为普通文件
True if file exists and is a regular file.
-g file :文件存在,且拥有SGID权限
True if file exists and is set-group-id.
-h file :存在且为符号链接文件
True if file exists and is a symbolic link.
-k file :存在,且拥有sticky权限
True if file exists and its ‘‘sticky’’ bit is set.
-p file :存在且为命名管道文件
True if file exists and is a named pipe (FIFO).
-r file :文件存在,且拥有读权限
True if file exists and is readable.
-s file :文件存在且非空
True if file exists and has a size greater than zero.
-t fd :fd表示文件描述符是否已经打开且与某终端相关
True if file descriptor fd is open and refers to a terminal.
-u file :存在,且拥有SUID权限
True if file exists and its set-user-id bit is set.
-w file :文件存在,且拥有写权限
True if file exists and is writable.
-x file :文件存在,且拥有执行权限
True if file exists and is executable.
-O file :当前有效用户是否为文件的属主
True if file exists and is owned by the effective user id.
-G file :当前有效用户是否为文件的属组
True if file exists and is owned by the effective group id.
-L file :存在且为符号链接文件
True if file exists and is a symbolic link.
-S file :存在且为套接字文件
True if file exists and is a socket.
-N file :文件自从上一次被读取后,是否被修改过
True if file exists and has been modified since it was last read.
file1 -nt file2:文件1是否新于文件2
True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.
file1 -ot file2:文件1是否旧与文件2
True if file1 is older than file2, or if file2 exists and file1 does not.
file1 -ef file2:文件1和文件2是否指向同一设备同一inode
True if file1 and file2 refer to the same device and inode numbers.
组合测试条件:
逻辑运算: 第一种方式:
命令1 && 命令2
命令1 || 命令2
! 命令
如:[ -e 文件1 ] && [ -r 文件2 ]
第二种方式:
表达式1 -a 表达式2
表达式1 -o 表达式2
! 表达式
必须使用测试命令进行
bash自定义退出状态码
exit [n] :自定义退出状态码: echo $? 查看退出码
注意:脚本中一旦遇到exit命令,脚本会立即终止。终止退出状态取决于exit命令后面的数字。
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码。
练习:
写一个脚本,接受一个文件路径作为参数,
如果参数小于1 ,则提示用户“至少应该给一个参数”,并立即退出。
如果参数不小于1,则显示第一个参数所指向的文件中的空白行数。