Linux 基础 (五)
一、shell相关知识
shell一般代表两个层面的意思,一个是命令解释器,比如BASH,另外一个就是shell脚本。通过解释器的角度来理解shel
命令分为:
==> alias(别名)
==> Compound Commands
==> function
==> build_in (内部命令)
==> hash
==> $PATH (外部命令)
==> error: command not found
获取一个命令会按照上述优先级取寻找,先找同名的alias命令,再找compound命令.........
别名:别名命令是为了简化输出给一个长参数命令的整合,别名的定义方法 alias la='ls -al' 取消别名 unalias la
内部命令:是BASH自带的命令 功能简单,内部命令的帮助在builtin(1)里
外部命令:是就是一个小程序存在于/bin/ /sbin/ /usr/bin 等地方
二、正则表达式
正则就是用来描述一类事物的规则
^ 行首
$ 行尾
. 除了换行符以外的任意单个字符
* 前导字符的零个或多个
.* 所有字符
[] 字符组内的任一字符
[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
^[^] 非字符组内的字符开头的行
[a-z] 小写字母
[A-Z] 大写字母
[a-Z] 小写和大写字母
[0-9] 数字
+左边的有1个或者无穷多个
?左边的字符有0个或者1个
\< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
\> 单词尾
三、文本编辑三剑客:grep 、sed 、awk
grep:
为了避免使用上的尴尬,以后就用egrep就OK
1)命令格式
egrep [cinvs] 'patten' filename
参数
-n :显示行号
-o :只显示匹配的内容
-q :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容
-l :如果匹配成功,则只将文件名打印出来,失败则不打印,通常-rl一起用,grep -rl 'root' /etc
-A :如果匹配成功,则将匹配行及其后n行一起打印出来
-B :如果匹配成功,则将匹配行及其前n行一起打印出来
-C :如果匹配成功,则将匹配行及其前后n行一起打印出来
--color
-c :如果匹配成功,则将匹配到的行数打印出来
-E :等于egrep,扩展
-i :忽略大小写
-v :取反,不匹配
-w:匹配单词
grep相关练习
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
目标文件/etc/passwd,使用grep命令或egrep 1.显示出所有含有root的行: cat /etc/passwd #显示passwd 的所有内容 egrep 'root' /etc/passwd #显示出所有含有root的行 2.输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的内容: egrep -C 2 "bash" /etc/passwd #输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的内容 3. 显示出有多少行含有nologin egrep -c "nologin" /etc/passwd #显示出有多少行含有nologin 4.显示出那些行含有root,并将行号一块输出。 egrep -n "nologin" /etc/passwd #显示出那些行含有root,并将行号一块输出 5.新建用户 abominable abominate anomie atomize 编写正则表达式,将他们匹配出来 egrep 'a.omi(nabl|nat|z|)e' /etc/passwd 6.建四个用户 Alex213sb Wpq2222b yH438PIG egon666 egon 过滤出用户名组成是字母+数字+字母的行 egrep '^[a-Z]+[0-9]+[a-Z]+' /etc/passwd 8.显示出/etc目录下所有包含root的文件名 egrep -rl 'root' /etc 9. 过滤掉/etc/ssh/sshd_config内所有注释和所有空行 grep -v '^#' /etc/ssh/sshd_config |grep -v '^ *$'
sed
流编辑器 stream editer,是以行为单位的处理程序
在使用过程中最好是记忆 sed -r xxxxx
sed [options] 'command' in_file[s]
options 部分
-n 使用安静(silent)模式
-e 直接在指令列模式上进行 sed 的动作编辑
-i 直接修改读取的档案内容,而不是由显示器输出
-f 直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作
command 部分
'[地址1,地址2] [函数] [参数(标记)]'
定址的方法 1.数字 2.正则
数字
十进制数
1 单行
1,3 范围 从第一行到第三行
2,+4 匹配行后若干行
4,~3 从第四行到下一个3的倍数行
2~3 第二行起每间隔三行的行
$ 尾行
1! 除了第一行以外的行
正则
正则必须用//包裹起来
删除某行 sed '$d' ab #删除最后一行
显示某行 sed -n '2,$p' ab #显示第二行到最后一行
增加一行或多行字符串 sed '1,3a drink tea' ab #第一行到第三行后增加字符串"drink tea"
代替一行或多行 sed '1,2c Hi' ab #第一行到第二行代替为Hi
替换一行中的某部分
格式:sed 's/要替换的字符串/新的字符串/g' (要替换的字符串可以用正则表达式)
sed -n '/ruby/p' ab | sed 's/ruby/bird/g' #替换ruby为bird
sed -n '/ruby/p' ab | sed 's/ruby//g' #删除ruby
sed 部分的练习题
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
ed作业:以/etc/passwd文件为模板 1,删除文件每行的第一个字符。 2,删除文件每行的第二个字符。 3,删除文件每行的最后一个字符。 4,删除文件每行的倒数第二个字符。 5,删除文件每行的第二个单词。 6,删除文件每行的倒数第二个单词。 7,删除文件每行的最后一个单词。 8,交换每行的第一个字符和第二个字符。 9,交换每行的第一个字符和第二个单词。 10,交换每行的第一个单词和最后一个单词。 11,删除一个文件中所有的数字。 12,删除每行开头的所有空格。 13,用制表符替换文件中出现的所有空格。 14,把所有大写字母用括号()括起来。 15,打印每行3次。 16,隔行删除。 17,把文件从第2行到第5行复制到第7行后面。(选做题) 18,把文件从第2行到第5行移动到第7行后面。(选做题) 19,只显示每行的第一个单词。 20,打印每行的第一个单词和第三个单词。 21,将格式为 mm/yy/dd 的日期格式换成 mm;yy;dd 22, a.txt内容 ABC DEF XYZ 通过SED实现tac命令 tac a.txt XYZ DEF ABC
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
准备工作:先将/etc/passwd 下的20行作为测试的环境 head -20 /etc/passwd >test cat test root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-bus-proxy:x:999:998:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:998:997:User for polkitd:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin unbound:x:997:995:Unbound DNS resolver:/etc/unbound:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin cat test1 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 1. sed -r 's/^(.)(.*)/\2/' test1 #删除文件每行的第一个字符 2.sed -r 's/^(.)(.)(.*)/\1\3/' test1 #删除文件每行的第二个字符 3.sed -r 's/(.*)(.)$/\1/' test1 #删除文件每行的最后一个字符 4.sed -r 's/(.*)(.)(.)$/\1\3/' test1 #删除文件每行的最后个第二字符 5.sed -r 's/^([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/\1\2\4/' test1 # 删除文件每行的第二个单词 6. sed -r 's/([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)$/\1\3\4/' test1 #删除文件每行的倒数第二个单词 7.sed -r 's/([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)$/\1\2\3/' test1 #删除文件每行的最后一个单词 8.sed -r 's/^(.)(.)(.*)$/\2\1\3/' test1 #交换每行的第一个字符和第二个字符 9.sed -r 's/^(.)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)/\4\2\3\1\5/' test1 # 交换每行的第一个字符和第二个单词 10. sed -r 's/[0-9]//g' test1 # 删除一个文件中所有的数字 11.sed -r 's/^ *//g' test1 #删除每行开头的所有空格 12.sed -r 's/ /\t/g' test1 #用制表符替换文件中出现的所有空格 13. sed -r 's/[A-Z]/(&)/g' test1 #把所有大写字母用括号()括起来 14. sed 'p;p' test1 #打印每行3次 15. sed '1~2d' test1 #隔行删除 创建文件test2 vim test2 [root@localhost gandong]# cat test2 11111111111 2222222222 333333333 4444444444 55555555555 6666666666 777777777777 888888888888 99999999999999 16. sed '2h;3,5H;7G' test2 #把文件从第2行到第5行复制到第7行后面 17. sed '2h;3,5H;2,5d;7G' test2 #把文件从第2行到第5行移动到第7行后面 18.sed -r 's/^([a-Z]+)([^a-Z]+)(.*)/\1/' test1 #只显示每行的第一个单词 19.sed -r 's/^([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)$/\1\ \5/' test1 # 打印每行的第一个单词和第三个单词 20.
awk
awk是一个非常好用的数字处理工具。相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分为数个“字段”来处理。运行效率高,而且代码简单,对格式化的文本处理能力超强。
awk的一般语法格式为:
awk [-参数 变量] 'BEGIN{初始化}条件类型1{动作1}条件类型2{动作2} 、、、、、END{后处理}'
或者为:awk [options] 'commands' files
NR变量定址
NR 表示AWK读入的行数
FNR表示读入行所在文件中的行数
逻辑运算 可直接引用域进行运算
== >= <= != > < ~ !~
# awk 'NR==1 {print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
1)参数说明:
-F re:允许awk更改其字段分隔符
-v var=$v 把v值赋值给var,如果有多个变量要赋值,那么就写多个-v,每个变量赋值对应一个-v
eg: 要打印文件a的第num行到num+num1行之间的行,
awk -v num=$num -v num1=$num1 'NR==num,NR==num+num1{print}' a
-f progfile:允许awk调用并执行progfile程序文件,当然progfile必须是一个符合awk语法的程序文件。
2)awk读取shell中的变量
可以使用-v选项实现功能
$b=1
$cat f
apple
$awk -v var=$b '{print var, $var}' f
1 apple
至于有没有办法把awk中的变量传给shell呢,这个问题我是这样理解的。shell调用awk实际上是fork一个子进程出来,而子进程是无法向父进程传递变量的,除非用重定向(包括管道)
a=$(awk '{print $b, '$b'}' f)
$echo $a
apple 1
注:此处内容参照:http://www.cnblogs.com/dong008259/archive/2011/12/06/2277287.html(如需了解请查阅)
3)输出重定向
awk的输出重定向类似于shell的重定向。重定向的目标文件名必须用双引号引用起来。
$awk '$4 >=70 {print $1,$2 > "destfile" }' filename
$awk '$4 >=70 {print $1,$2 >> "destfile" }' filename
练习题目:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1.打印uid在30~40范围内的用户名。 2.打印第5-10行的行号和用户名 3.打印奇数行 4.打印偶数行 5.打印字段数大于5的行 6.打印UID不等于GID的用户名 7.打印没有指定shell的用户 8.打印1..1000以内的7的倍数和包含7的数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
先创建测试文档 head -20 /etc/passwd >test #把 /etc/passwd下的前五行内容输出到文件test 中 cat test #查看test1文件内容 cat test cat test root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-bus-proxy:x:999:998:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:998:997:User for polkitd:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin unbound:x:997:995:Unbound DNS resolver:/etc/unbound:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin [root@localhost gandong]# cat test1 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 1.awk -F: '$3>29&&$3<41{print $1}' test #打印uid在30~40范围内的用户名 1.awk -F: '$3>=30&&$3<=40{print $1}' test 2.awk -F: 'NR>4&&NR<11{print $1,NR}' test #打印第五到第十行的行号及用户名 3.awk -F: 'NR%2{ print NR,$0}' test #打印奇数行 4.awk -F: '!(NR%2){print NR,$0}' test #打印偶数行 5.awk -F: 'NF>5{print NR,$0}' test #打印字段数大于5的行 6. awk -F: '$3!=$4{print NR,$1}' test #打印UID不等于GID的用户名
四、test命令
1.定义变量名的边界
eg:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost gandong]# x=3 [root@localhost gandong]# echo ${x}% 3%
2.运算符(+ — * / %)
eg:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost gandong]# echo $[3+1] 4
3.关系操作符号(>、 >=、 <、 <=、==、!=、&&、|| )
eg:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost ~]# x=1 [root@localhost ~]# [ $x -gt 1 ] [root@localhost ~]# echo $? 1
4.赋值运算(=、+=、*=、/=、%=)
eg:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost ~]# x=10 [root@localhost ~]# [ x%3 ] [root@localhost ~]# echo $x 10 [root@localhost ~]# ((x%3)) [root@localhost ~]# echo $x 10 [root@localhost ~]# ((x%=3)) [root@localhost ~]# echo $x 1
浮点运算:yum install bc -y(安装用于计算浮点类型的数据)
eg:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost ~]# echo 'scale=2;1/3' |bc -l .33 [root@localhost ~]# echo 'scale=2;1/3' |bc -l |cut -d. -f2 33
五、测试操作
命令执行后会返回到一个系统变量中 $?
如果$?值为0 表示命令执行成功 否则为失败
测试命令 test [ ] [[ ]] (( ))
打开man test 逐一介绍每个参数
-d :目录 test -d /boot
-s :文件长度 > 0、非空 test -s a.txt
-f :正规文件 test -f a.txt
-w :可写 test -w a.txt
-r :可读 test -r a.txt
-x :可执行 test -x a.txt
-L :符号连接
-u :文件有 suid 位设置
-z :空串
-n :非空串
-eq :等于 [ 50 -eq 50 ]
-ne :不等于 [ 50 -ne 60 ]
-gt :大于 (great than) [ 50 -gt 40 ]
-lt :小于 (less than ) [ 50 -lt 60 ]
-ge :大于等于 [ 50 -ge 50 ]
-le :小于等于 [ 50 -le 50 ]
比较数字,使用(( ))
其他测试使用 [[ ]]
包含数字比较的混合测试,使用[[ expr1 && expr2 ]] (( expr1 || expr2 ))
du -sh /boot/ #查看文件大小
find / -type f #查看普通文件
find / -name "*.txt" #查看根下以.txt结尾的文件
find / -size +30M #找出根下大于30M的文件
find / -size +10M -size +30M #找出根下大于10M且小于30M的文件
grep -rl 'root' /test #在/test下找出含root名的文件
混合测试练习:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[root@localhost ~]# [[ a = a&& 10 < 20 ]] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ a = a || 10 < 20 ]] [root@localhost ~]# echo $? 0