Linux05_01?egrep使用和扩展正则表达式
REGEXP:REGular EXPression,其本身可能并不表示其本身的意思,而是做锚定等特殊意义的
Pattern: 由正则表达式元字符和字符组合起来用于过滤文本的过滤条件
正则表达式:
Basic REGEXP:基本
Extended REGEXP:扩展
基本正则表达式:
.:
[]:
[^]:
次数匹配:
*:
\?: 0或1次
\{m,n\}:至少m次,至多n次;
.*:
锚定:
^:
$:
\<, \b:
\>, \b:
\(\)
\1, \2, \3, ...
grep:使用基本正则表达式定义的模式来过滤文本的命令;
-i:忽略大小写
-v:显示没有匹配的
-o:只显示被模式匹配到的字符串
--color:匹配出的字符串加上颜色
-E: 使用扩展正则表达式
----------------------------------------
-A n: 用于显示匹配到了的行的after n行
-B n: 用于显示匹配到了的行的before n行
-C n: 用于显示匹配到了的行的context n行
[root@localhost ~]# grep --color -C 1 ‘^cpu‘ /proc/cpuinfo
vendor_id : GenuineIntel
cpu family : 6
model : 42
--
stepping : 7
cpu MHz : 2394.571
cache size : 3072 KB
--
fpu_exception : yes
cpuid level : 13
wp : yes
---------------------------------------------
扩展正则表达式:
字符匹配:和正则表达式一样
.
[]
[^]
次数匹配:
*:
?:不需要\
+: 匹配其前面的字符至少1次
{m,n}:不需要\
位置锚定:和正则表达式一样
^
$
\<
\>
分组:
():真正意义上分组,不需要\
\1, \2, \3, ...
或者
|: 表示or的意思
C|cat: C或cat
(C|c)at:Cat或cat
grep -E = egrep
255 :
一位:9 [0-9]
二位:99 [1-9][0-9]
三位:199 1[0-9][0-9]; 249 2[0-4][0-9]; 255 2[0-5][0-5]
通过上面的可以退出:\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>
4、显示所有以数字结尾且文件名中不包含空白的文件;
ls *[^[:space:]]*[0-9] ?????????
找出/boot/grub/grub.conf文件中1-255之间的数字;
\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>
\.
ifconfig | egrep ‘\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>‘
ifconfig | egrep --color ‘(\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.){3}\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>‘
IPv4:
5类:A B C D E
A:1-127 : 00000000:0:0:0~01111111:255:255:255 一段网络
B:128-191 10000000:0:0:0~10111111:255:255:255 二段网络
C:192-223 11000000:0:0:0~11000000:255:255:255 三段网络
\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>){2}\.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>
http://mageedu.blog.51cto.com/
grep, egrep
fgrep: 不支持正则表达式
逻辑运算:与、或、非、异或
1: 真
0: 假
与:&
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
1 & 1 = 1
或:!
非:
! 真 = 假
! 假 = 真
shell: 弱类型编程语言
强:变量在使用前,必须事先声明,甚至还需要初始化;
弱:变量用时声明,甚至不区分类型;
变量赋值:VAR_NAME=VALUE
bash变量类型:
环境变量
本地变量(局部变量)
位置变量:\1,\2..
特殊变量
本地变量:
set VARNAME=VALUE: 作用域为整个bash进程;
---------------------------------
[root@localhost ~]# NAME=lvyongwen (没有写类型是因为shell是弱类型的)
[root@localhost ~]# echo $NAME (可以打印出)
lvyongwen
[root@localhost ~]# bash (子shell在shell中再开启一个shell进程)
[root@localhost ~]# echo $NAME (打印不出,是因为本地变量作用范围是整个shell进程,子shell得不到)
[root@localhost ~]# exit
exit
[root@localhost ~]# echo $NAME
lvyongwen
[root@localhost ~]#
引用变量:${VARNAME} {}假如不会引起歧义的可以省略
[root@localhost ~]# NAME=lvyongwen
[root@localhost ~]# echo "My name is ${NAME}"
My name is lvyongwen
[root@localhost ~]# echo "My name is $NAME"
My name is lvyongwen
[root@localhost ~]# echo "My name is $NAMEq"
My name is
[root@localhost ~]# echo "My name is ${NAME}q"
My name is lvyongwenq
[root@localhost ~]# echo ‘My name is ${NAME}q‘
My name is ${NAME}q 没有打印出名字是因为‘‘为强引用类型,不能变量替换而""是弱类型所以可以
[root@localhost ~]#
------------------------------------
局部变量:
local VARNAME=VALUE:作用域为当前代码段;
环境变量:作用域为当前shell进程及其子进程;
定义变量1:
export VARNAME=VALUE
定义变量2:
VARNAME=VALUE
export VARNAME
“导出”
位置变量:
$1, $2, ...
特殊变量:
$?: 上一个命令的执行状态返回值;
程序执行,可能有两类返回值:
程序执行结果
程序状态返回代码(0-255)
0: 正确执行
1-255:错误执行,1,2,127系统预留;
[root@localhost ~]# ls
anaconda-ks.cfg DOS install.log test vms
C exit install.log.syslog test_dir
Desktop grant Solaris Unix
[root@localhost ~]# echo $?
0
[root@localhost ~]# lll
bash: lll: command not found
[root@localhost ~]# echo $?
127
[root@localhost ~]# ls /ss
ls: /ss: No such file or directory
[root@localhost ~]# echo $?
2
-------------------------------------
输出重定向:
>
>>
2>
2>>
&>
/dev/null: 软件设备, bit bucket(桶),数据黑洞
[root@localhost ~]# ls &> /dev/null -->所输出的结果将被吃掉
[root@localhost ~]# echo $?
0
------------------------------------------
撤消变量:
unset VARNAME
查看当shell中变量:本地和环境变量
set
查看当前shell中的环境变量:
printenv
env
export
变量存入到内存中是字符串
[root@localhost ~]# A=2
[root@localhost ~]# B=3
[root@localhost ~]# C=$A+$B
[root@localhost ~]# echo $C
2+3 <<---这里可以说明上述点
脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序
-------------------------
Linux内核只识别:ELF文件类型:Executable link file
[root@localhost ~]# file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64...
[root@localhost ~]# file ./test
./test: ASCII text
对于纯文本需要下面shebang告诉Linux内核启动解释器来解释
shebang: 魔数
#!/bin/bash
# 注释行,不执行
----
[root@localhost ~]# cat adduser.sh
#!/bin/bash <--表示需要Linux调用Linux内核解释器才能执行
adduser user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."
[root@localhost ~]# bash adduser.sh <--作为参数而执行,
Add user1 successfully.
[root@localhost ~]# tail -1 /etc/passwd
user1:x:5001:5001::/home/user1:/bin/bash
[root@localhost ~]# nano adduser.sh
[root@localhost ~]# adduser.sh <--由于没有在PATH环境变量中配置
bash: adduser.sh: command not found
[root@localhost ~]# ./adduser.sh <--没有赋值可执行权限
bash: ./adduser.sh: Permission denied
[root@localhost ~]# ls -l
total 72
-rw-r--r-- 1 root root 107 Feb 1 22:45 adduser.sh//虽然显示绿色是因为.sh默认会这样显示
[root@localhost ~]# chmod +x adduser.sh
[root@localhost ~]# ./adduser.sh
Add user1 successfully.
[root@localhost ~]#
------------------------
脚本在执行时会启动一个子shell进程;
命令行中启动的脚本会继承当前shell环境变量;
系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量;
练习:写一个脚本,完成以下任务
1、添加5个用户, user1,..., user5
2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;
3、每个用户添加完成后,都要显示用户某某已经成功添加;
useradd user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."
练习:写一个脚本,完成以下任务
1、使用一个变量保存一个用户名;
2、删除此变量中的用户,且一并删除其家目录;
3、显示“用户删除完成”类的信息;
[root@localhost ~]# clear
[root@localhost ~]# cat userdel.sh
#!/bin/bash
USERNAME=user02
userdel -r $USERNAME --> -r表示目录邮件一并删除
echo "delete user successfully!"
Linux05_03?bash脚本编程之一条件判断
条件判断:
如果用户不存在
添加用户,给密码并显示添加成功;
否则
显示如果已经没在,没有添加;
bash中如何实现条件判断?
条件测试类型:
整数测试
字符测试
文件测试
条件测试的表达式:
[ expression ]
[[ expression ]]
test expression
整数比较:
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于
命令的间逻辑关系:
逻辑与: &&
第一个条件为假时,第二条件不用再判断,最终结果已经有;
第一个条件为真时,第二条件必须得判断;
逻辑或: ||
第一个条件为真时,第二条件不用再判断,最终结果已经有;
第一个条件为假时,第二条件必须得判断;
逻辑非:!//单目
如果用户user6不存在,就添加用户user6
! id user6 && useradd user6
id user6 || useradd user6
如果/etc/inittab文件的行数大于100,就显示好大的文件;
[ `wc -l /etc/inittab | cut -d‘ ‘ -f1` -gt 100 ] && echo "Large file."
变量名称:
1、只能包含字母、数字和下划线,并且不能数字开头;
2、不应该跟系统中已有的环境变量重名;
3、最好做到见名知义;
如果用户存在,就显示用户已存在;否则,就添加此用户;
id user1 && echo "user1 exists." || useradd user1
如果用户不存在,就添加;否则,显示其已经存在;
! id user1 && useradd user1 || echo "user1 exists."
如果用户不存在,添加并且给密码;否则,显示其已经存在;
! id user1 && useradd user1 && echo "user1" | passwd --stdi× user1 || echo "user1 exists."
练习,写一个脚本,完成以下要求:
1、添加3个用户user1, user2, user3;但要先判断用户是否存在,不存在而后再添加;
! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo "user1 exists"
2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
3、最后显示当前系统上共有多少个用户;
一种:
COUNT=`wc -l /etc/passwd | cut -d‘ ‘ -f1`
echo "$COUNT users"
二种:
echo ‘this system users counts is `wc -l /etc/passwd | cut -d‘ ‘ -f1`‘×
echo "this system users counts is `wc -l /etc/passwd | cut -d‘ ‘ -f1`"√
---------------------------------
[root@localhost ~]# echo "$NAMES"-->说明弱引用可以引用变量替换
lvyongwen
[root@localhost ~]# echo ‘$NAMES‘-->说明强引用不可以引用变量替换
$NAMES
[root@localhost ~]# echo ‘"$NAMES"‘-->强引用不可以嵌套弱引用引用变量
"$NAMES"
[root@localhost ~]# echo "`ls ./`"
adduser.sh
......
[root@localhost ~]# echo ‘`ls ./`‘
`ls ./`
上面两个结果说明:
反向引用可以命令替换,而且弱引用可以嵌套反向引用引用命令而强引用不可以
[root@localhost ~]# echo "ls ./"-->说明弱引用不可以命令替换
ls ./
[root@localhost ~]# echo `$NAMES`
-bash: lvyongwen: command not found
由于反向引用认为引用的是命令,所以会报命令未找到,而且可以说明反向引用会引用变量
[root@localhost ~]# echo `id $NAMES`
uid=500(lvyongwen) gid=500(lvyongwen) groups=500(lvyongwen)
[root@localhost ~]#
---------------------------------
练习,写一个脚本,完成以下要求:
给定一个用户:
1、如果其UID为0,就显示此为管理员;
2、否则,就显示其为普通用户;
一种:
NAME="root"
[ `grep "^$NAME" /etc/passwd | cut -d: -f3` -eq 0 ] -->说明反向引用可以嵌套弱引用引用变量
&& echo "this user is root"
|| "this user is not root"
二种:
NAME=user1
USERID=`id -u $NAME` -->说明反向引用可以引用变量
[$USERID -eq 0] && echo "Adim" || echo "Commom user"
如果 UID为0;那么
显示为管理员
否则
显示为普通用户
NAME=user16
USERID=`id -u $NAME` -->使用命令的执行结果
if [ $USERID -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
NAME=user16
if [ `id -u $NAME` -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
if id $NAME; then -->使用命令的执行状态结果