egrep 及扩展的正则表达式
egrep = grep -E 支持的选项同 grep,和 grep 同属一个命令手册
扩展正则表达式的元字符:
? 字符匹配:. [] [^]
? 次数匹配:* ? + {m} {m,n}
? 锚定:^ $ \< \>
? 分组:() \1 \2
? |(或者):C|cat 表示 C 或 cat
练习:
1、显示当前系统 root、centos 或 user1 用户的默认 shell 和 UID
[root@laptop-u5s7ejrh ~]
2、找出 /etc/rc.d/init.d/functions 文件中某单词后面跟一个小括号的行
[root@laptop-u5s7ejrh init.d]
3、使用 echo 输出一绝对路径,使用 egrep 取出其基名,类似于 basename 命令
[root@laptop-u5s7ejrh init.d]
fgrep 不支持正则表达式搜索,只是单纯的匹配字符或字符串
bash 的基础特性(4)
变量类型:数据存储格式、存储空间大小、参与运算种类;
? 字符型、数值型(整型、浮点型)
? 强类型:定义变量时必须指定类型、参与运算必须符合类型要求,调用未声明变量会产生错误
? 弱类型:无需指定类型,默认均为字符型,参与运算会自动进行隐试类型转换,变量无须事先定义可直接调用,bash 属于此种
bash 中的变量种类:
? 根据变量的生效范围等标准:
? 本地变量:生效范围为当前 shell 进程;对当前 shell 之外的其它 shell 进程,包括当前 shell 的子 shell 进程均无效
? 环境变量:生效范围为当前 shell 进程及其子进程
? 局部变量:生效范围为当前 shell 进程中某代码片段(通常指函数)
? 位置变量:$1,$2,··· 来表示,用于让脚本在脚本代码中调用通过命令行传递给她的参数
? 特殊变量:$?,
0
,
0,
0,*,
@
,
@,
@,#
? 1、本地变量
变量赋值:name='value'
可以使用引用(对于value)
(1)直接是字符串 name="username"
(2)变量引用 name="$username"或"${username}"
"":弱引用,其中的变量引用会被替换成变量值
'':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
(3)命令引用 name='COMMAND',name=$(COMMAND)
显示已定义的所有变量:set
销毁变量:unset name
例1:这里传递的是命令的执行结果(结果的返回值),非命令的状态结果(判断命令执行成功与否)
[root@localhost ~]
[root@localhost ~]
1000
例2:强引用和弱引用的区别
[root@localhost ~]
[root@localhost ~]
$userid
[root@localhost ~]
[root@localhost ~]
1000
2、环境变量
变量声明、赋值:export name=VALUE 或 declare -x name=VALUE
变量引用:$name,${name}
显示所有环境变量:export、env、printenv
销毁:unset name
3、只读变量
readonly name
declare -r name
4、位置变量
在脚本代码中调用通过命令行传递给脚本的参数
$1,$2,··· 对应调用第1、第2等参数
$0:命令本身
$*:传递给脚本的所有参数
$@:传递给脚本的所有参数
$#:传递给脚本的参数的个数
例1:
[root@localhost mnt]
echo $0
echo $1
echo $2
echo "\$*: $*"
echo "\$@: $@"
echo "\$#: $#"
[root@localhost mnt]
[root@localhost mnt]
./text.sh
Tom
Jerry
$*: Tom Jerry
$@: Tom Jerry
$#: 2
例2:判断给出的文件行数
[root@localhost mnt]
linecount="$(wc -l $1 | cut -d' ' -f1)"
echo "$1 has $lincount lines."
**bash 的配置文件 **
按生效范围划分:
? 全局配置:/etc/profile、/etc/profile.d/*.sh、/etc/bashrc
? 个人配置:/.bash_profile、/.bashrc
按功能划分:
? profile 类:为交互式登录的 shell 提供配置
? 全局:/etc/profile、/etc/profile.d/*.sh
? 个人:~/.bash_profile
? 功用:用于定义环境变量;运行命令或脚本
? bashrc 类:为非交互式登录的 shell 提供配置
? 全局:/etc/bashrc
? 个人:~/.bashrc
? 功用:定义命令别名;定义本地变量
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
? 编辑配置文件定义的新配置的生效方式:
? (1)重新启动 shell 进程
? (2)使用 source 或 .命令进程
bash 中的算术运算
+ - * / % **
实现算术运算:
? (1)let var = 算术表达式
? (2)var=$[算术表达式]
? (3)var=$((算术表达式))
? (4)var=$(expr arg1 arg2 arg3 …)
注:乘法符号有些场景中需要转义;bash有内建的随机数生成器:$RANDOM
(1)
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
5
(2)
[root@localhost ~]
The sum is 5
(3)
[root@localhost ~]
The sum is 5
(4)
[root@localhost ~]
[root@localhost ~]
6
[root@localhost ~]
6
(5)
[root@localhost ~]
21094
[root@localhost ~]
12873
增强型赋值:
? +=, -=, *=, /=, %=
? let varOPERvalue 例如:let count+=1
? 自增,自减: let var+=1 let var++ let var-=1 let var–
练习:
1、写一个脚本,计算 /etc/passwd 文件中的第 10 个用户和第 20 个用户的 ID 之和
[root@192 mnt]
userid1=$(head -n 10 /etc/passwd | tail -n 1 | cut -d : -f 3)
userid2=$(head -n 20 /etc/passwd | tail -n 1 | cut -d : -f 3)
useridsum=$[$userid1+$userid2]
echo "The uid sum: $useridsum"
2、写一个脚本,传递两个文件路径作为参数脚本,计算这两个文件中所有空白之和
[root@192 mnt]
spaceline1=$(grep "^[[:space:]]*$" $1 | wc -l)
spaceline2=$(grep "^[[:space:]]*$" $2 | wc -l)
echo "The sum: $[$spacelin1+spaceline2]"
条件测试:
? 判断某需求是否满足,需要由测试机制来实现(专用的测试表达式需要由测试命令辅助完成测试过程)
? 测试命令: test EXPRESSION、
? test [ EXPRESSION ] [ ] 表示一个命令
? test [[ EXPRESSION ]] [[ ]] 表示的是bash中一个内置的保留关键字
? 注:在括号里面的表达式前后一定有空白字符
? bash 中的测试类型:
数值测试:
-gt: 是否大于;
-ge: 是否大于等于;
-eq: 是否等于;
-ne: 是否不等于;
-lt: 是否小于;
-le: 是否小于等于;
[root@localhost ~]
[root@localhost ~]
0
字符串测试:
==:是否等于;
>: 是否大于;
<: 是否小于;
!=: 是否不等于;
=~: 左侧字符串是否能够被右侧的PATTERN所匹配
Note: 此表达式一般用于[[ ]]中
-z "STRING":测试字符串是否为空,空则为真,不空则为假
-n "STRING":测试字符串是否不空,不空则为真,空则为假
例1:
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
1
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
0
例2:
[root@localhost ~]
[root@localhost ~]
0
Note:用于字符串比较时的用到的操作数都应该使用引号
文件测试
bash 自定义退出状态码
? exit [n]:自定义退出状态码
? 注:脚本中一旦遇到 exit 命令,脚本会立即终止;终止退出状态取决于 exit 命令后面的数字
? 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
练习:
1、写一个脚本,接受一个文件路径作为参数,如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
[root@192 mnt]
[ $# -lt 1 ] && echo "At least one Arg" && exit 1
spceline=$(grep "^[[:space:]]*$" $1 | wc -l)
echo "The Spaceline: $spceline"
vim 编辑器
简介:vi 是文本(ASCII、Unicode)编辑器,VIM 是 Vi 的增强版,采用模式化的编辑。
? 基本模式:编辑模式(命令模式)、输入模式、末行模式,采用内置的命令行接口。
1、打开文件:#vim [OPTION]… FILE…
? +#: 打开文件后,直接让光标处于第#行的行首;
? +/PATTERN:打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首;
? 模式转换:
? 编辑模式 --> 输入模式
i: insert, 在光标所在处输入;
a: append, 在光标所在处后面输入;
o: 在当前光标所在行的下方打开一个新行;
I:在当前光标所在行的行首输入;
A:在当前光标所在行的行尾输入;
O:在当前光标所在行的上方打开一个新行;
? 输入模式 --> 编辑模式 ESC
? 编辑模式 --> 末行模式 :
? 末行模式 --> 编辑模式 ESC
2、关闭文件
:q 退出
:q! 强制退出,丢弃做出的修改;
:wq 保存退出
:x 保存退出
:w /PATH/TO/SOMEWHERE
ZZ: 保存退出;
3、光标跳转
(1)字符间跳转:h、j、k、l
? h:左、l:右、j:下、k:上
? #COMMAND:跳转由 # 指定的个数的字符
(2)单词间跳转
? w:下一个单词的词首
? e:当前或下一单词的词尾
? b:当前或前一单词的词首
? #COMMAND:由 # 指定一次跳转的单词数行首行尾跳转
? ^:跳转至行首的第一个非空白字符
? 0:跳转至行首
? $:跳转至行尾
(3)行间移动
? #G:跳转至由#指定航
? G:最后一行
? 1G,gg:第一行
(4)句间移动 )、(
(5)段落间移动 }、{
vim编辑命令
(1)字符编辑
? x:删除光标处的字符
? #x:删除光标处起始的#个字符
? xp:交换光标所在处的字符及其后面字符的位置
(2)替换命令
? r:替换光标所在处的字符
(3)删除命令
? d:删除命令,可结合光标跳转字符,实现范围删除
? dd:删除光标所在的行
? #dd:多行删除
(4)粘贴命令
? p:缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,则粘贴至当前光标所在处的后面;
? P:缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴至当前光标所在处的前面;
(5)复制命令
? y:复制,工作行为类似于d命令,参考删除命令
(6)改变命令
? c: 修改,编辑模式 --> 输入模式
? c$ ? c^ ? c0 ? cb ? ce ? cw ? #COMMAND ? cc:删除并输入新内容 ? #cc:
(7)翻屏操作
? Ctrl + f:向文件尾部翻一屏
? Ctrl+b: 向文件首部翻一屏;
? Ctrl+d: 向文件尾部翻半屏;
? Ctrl+u:向文件首部翻半屏;
(8)其它编辑操作
? 可视化模式 v:按字符选定 V:按行选定
? 撤销此前的编辑 u:撤销此前的操作 #u:撤销指定次数的操作
? 撤销此前的撤销 Ctrl + r
? 重复前一个编辑操作 .
vim 自带练习教程 vimtutor
vim 中的末行模式
(1)地址定界 :start_pos,end_pos
.: 当前行
$: 最后一行
.,$-1
%:全文, 相当于1,$
/pat1/,/pat2/:从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束;
pat/,
? 使用方式:后跟一个编辑命令
d
y
w /PATH/TO/SOMEWHERE 将范围内的行另存至指定文件中
:1,10w /mnt/file11
r /PATH/FROM/SOMEFILE 在指定位置后插入指定文件中的所有内容
:18r /mnt/file11
(2)查找
/PATTERN:从当前光标所在处向文件尾部查找;
?PATTERN:从当前光标所在处向文件首部查找;
n:与命令同方向
N:与命令反方向
例:
?\<love\> 从当前光标处向文件首部查找love这个单词
(3)查找并替换
s: 在末行模式下完成查找替换操作
s/要查找的内容/替换为的内容/修饰符
要查找的内容:可使用模式
替换为的内容:不能使用模式,但可以使用\1, \2, ...等后向引用符号;还可以使用“&”引用前面查找时查找到的整个内容;
修饰符:
i: 忽略大小写
g: 全局替换;默认情况下,每一行只替换第一次出现;
查找替换中的分隔符/可替换为其它字符,否则就要用到转义符,例如
s@@@
s
例:
:%s/\/etc\/fstab/\/var\/log/g 或
:%s@/var/log@/etc/fstab@g
练习:
1、复制/etc/grub2.cfg至/tmp/目录,用查找替换命令删除/tmp/grub2.cfg文件中的行首的空白字符
:%s/^[[:space:]]\+//g
2、复制/etc/rc.d/init.d/functions文件至/tmp 目录,用查找替换命令为/tmp/functions的每行开头为空白字符的行的行首添加一个#号
:%s/^[[:space:]]/#&/
多文件模式
vim FILE1 FILE2 FILE3 ...
:next 下一个
:prev 前一个
:first 第一个
:last 最后一个
:wall 保存所有
:qall 退出所有
窗口分割模式
vim -o|-O FILE1 FILE2 ...
-o: 水平分割
-O: 垂直分割
在窗口间切换:Ctrl+w, Arrow
单文件窗口分割:
Ctrl+w,s: split, 水平分割
Ctrl+w,v: vertical, 垂直分割
定制vim的工作特性
? 配置文件:永久有效
? 全局:/etc/vimrc
? 个人:~/.vimrc
? 末行:当前vim进程有效
(1) 行号
显示:set number, 简写为set nu
取消显示:set nonumber, 简写为set nonu
(2) 括号匹配
匹配:set showmatch, 简写为set sm
取消:set nosm
(3) 自动缩进
启用:set ai
禁用:set noai
(4) 高亮搜索
启用:set hlsearch
禁用:set nohlsearch
(5) 语法高亮
启用:syntax on
禁用:syntax off
(6) 忽略字符的大小写
启用:set ic
不忽略:set noic
获取帮助:
:help
:help subject
练习:
1、复制/etc/rc.d/init.d/functions文件至/tmp目录;替换 /tmp/functions文件中的/etc/sysconfig/init为/var/log
:%s@/etc/sysconfig/init@/var/log@g
2、删除/tmp/functions文件中所有以#开头,且#后面至少有一个空白字符的行的行首的#号
注:在一个文本中;# hello # 后面带有空格的表示是纯注释,是可以删除的;#hello 没有空格的,表示这是一个可以启用的参数
bash条件测试之文件测试
文件测试
? 存在性测试
-a FILE
-e FILE: 文件存在性测试,存在为真,否则为假
[root@localhost mnt]
[root@localhost mnt]
0
? 存在性及类别测试
-b FILE:是否存在且为块设备文件;
-c FILE:是否存在且为字符设备文件;
-d FILE:是否存在且为目录文件;
-f FILE:是否存在且为普通文件;
-h FILE 或 -L FILE:存在且为符号链接文件;
-p FILE:是否存在且为命名管道文件;
-S FILE:是否存在且为套接字文件;
? 文件权限测试
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
? 文件特殊权限测试
-g FILE:是否存在且拥有sgid权限;
-u FILE:是否存在且拥有suid权限;
-k FILE:是否存在且拥有sticky权限
? 文件大小测试
-s FILE: 是否存在且非空
? 文件是否打开
-t fd: fd表示文件描述符是否已经打开且与某终端相关
? 其他
-N FILE:文件自动上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
? 双目测试
FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2
FILE1 -ot FILE2: FILE1是否旧于FILE2
组合测试条件
? 逻辑运算
第一种方式:
COMMAND1 && COMMAND2
COMMAND1 || COMMAND2
! COMMAND
例:
[ -e FILE ] && [ -r FILE ]
第二种方式:
EXPRESSION1 -a EXPRESSION2
EXPRESSION1 -o EXPRESSION2
! EXPRESSION
必须使用测试命令进行
例:
[root@localhost mnt]
localhost.localdomain
[root@localhost mnt]
(1)[root@localhost mnt]
(2)[root@localhost mnt]
?
|