shell编程
- 考虑了下,只是自己的一点记录,就按照自己的情况进行记录吧,后续有新的东西再随时补充。嗯呢~~
1. 几个命令
1) !n:可执行history中的第n个命令
2) set:查看全部的环境变量
3) env:可查看当前的环境变量
4) unset (环境变量) (注意:如果是在父进程定义的环境变量,那么在子进程中该变量就不能被删除
5) alias :别名,简单设置你的命令,下面利用alias实现一个简单的HTTP服务
效果类似:
注:如果需要设置重启依旧生效的话可以将alias写入~/.bashrc 这同设置 ~/.vimrc 方式是一样的,需要立即生效请使用source(.) ~/.bashrc即可
6) wc:统计数量
常用选项:
-l (line) :统计行数
-m (chars) :统计字符数
-w (words) :统计词数
比如:
测试用例:
1 #!/bin/bash 2 echo "行数:" 3 echo $(wc -l test.txt) 4 echo "字符数:" 5 echo $(wc -m test.txt) 6 echo "单词数:" 7 echo $(wc -w test.txt)
输出:
7) sort : 排序
格式: sort [-命令] [源文件] [-o 输出文件]
常用命令:
-b(ignore-leading-blanks):忽略每行前面的空格
-f(ignore-case):忽略大小写字母
-n(numeric-sort):按照数值排序
-r(reverse):按照相反的顺序排序
-t(field-separator):指定分隔符
-k n,m (key):指定范围
-u(unique):去除重复行
测试文件:/etc/passwd
测试要点:以/etc/passwd的第三列按照数字的降序进行排列
8) cut :按格式剪切字符
常用命令:
-d(delimiter):指定分隔符
-f(fields):选定列数
测试文件:/etc/passwd
10) uniq:去重复的行
常用命令:
-c :统计重复行数,并把行数显示在前面
11) tr:替换字符(或使用sed),支持正则表达式的使用
常用命令:
-d:删除某个字符
-s:把重复的字符都去掉
转换大小写:
删除某字符或显示不重复的字符:
12)split:切割文档
常用选项:
-b:根据大小来分割文档,单位byte
-l:根据行数来分割文档
分割:
其中splite3.txtaa-splite3.txtac为自动分割,分割前注意大小
13)sed:见下面的简单正则表达式说明
14)awk:见下面的简单正则表达式说明
2. 设置PATH,命令(库)查找的路径
1)假设在/home/test/路径下创建了test.sh
1 #!/bin/bash 2 echo "运行成功,设置PATH成功!"
2) 1.修改test的权限:chmod +x test.sh;
2.设置PATH="$PATH":"$PWD"
3.echo $PATH 查看我们设置的结果
不出意外的话,你可以看到这样的结果:
3)设置成功,你可以到任意路径下,执行test.sh
3.重定向说明
几个简单的实例:
1.输入重定向
2. 输出合并
另注: stdin的文件描述符为0,stdout=1,stderr=2;在重定向的时候可以选择cat test1.txt 2 > test3.txt
2)/dev/null : 丢弃输出
4.运算符说明/(test)
1) expr:算术运算符
简单测试:
1 #!/bin/bash 2 a=30 3 b=2 4 val=`expr $a + $b` 5 #注意: 6 #1."`"为ESC下面的按键,不是单引号 7 #2.运算符号两边的空格不能省略即$a + $b 不能写成$a+$b 8 echo "a + b = $val" 9 10 val=`expr $a / $b` 11 echo "a / b = $val"
这里再提示两个注意点:
1."`"为ESC下面的按键,不是单引号
2.运算符号两边的空格不能省略即$a + $b 不能写成$a+$b
结果:
另外可以采用双括号替代expr:
1 #!/bin/bash 2 a=1 3 b=2 4 #方法一:使用expr 注意两个变量中间的空格不可省略 5 c=$(expr $a + $b) 6 echo "结果c=$c" 7 8 #方法二:使用$(()) 或 $[] 9 d=$(($a+$b)) #推荐 10 f=$[$a+$b] 11 echo "d= $d" 12 echo "f= $f"
2) 逻辑运算符
3) 关系运算符
1. 数字关系运算符
1 #!/bin/bash 2 3 read -p "请输入你要比较的两个数,第一个数 = " a 4 read -p "请输入你要比较的两个数,第二个数 = " b 5 6 if [ $a -eq $b ] 7 then 8 echo "两个数相等" 9 elif [ $a -gt $b ] 10 then 11 echo "第一个数大于第二个数" 12 else 13 echo "第一个数小于第二个数" 14 fi
结果:
2. 字符串关系运算符
例子类似3.1,略。
4) 文件测试运算符
例子类似3.1,略。
6.在shell 中获取指令的结果
1)在双引号之间执行指令(其实上例解释算术运算符(expr)就是采用这样的方式)
1 #!/bin/bash 2 USER=`whoami` 3 echo "当前用户为:$USER"
输出:
2)获取指令执行结果($)
1 #!/bin/bash 2 3 echo "当前脚本的文件名:$0" 4 5 if [ -z $1 ] 6 then 7 echo "当前未输入参数" 8 else 9 echo "当前的第一个参数为:$1" 10 echo "参数总数为:$#" 11 fi 12 13 ##################################### 14 ### $@ 和 "$@" 、$* 和 "$*" 的比较 15 #################################### 16 for i in $* 17 do 18 echo "\$*循环,当前 i = $i" 19 done 20 21 for i in "$*" 22 do 23 echo "\"\$*\" 循环,当前 i = $i" #此时$i表示将参数看成一个整体 24 done 25 26 for i in $@ 27 do 28 echo "\$@循环 $i,当前 i = $i" 29 done 30 31 for i in "$@" 32 do 33 echo "\"\$@\" 循环,当前 i = $i" 34 done 35 36 37 38 echo "执行脚本的PID = $$" 39 40 echo "执行 whoami 指令:" 41 whoami 42 echo "执行返回的结果:$?" 43 44 echo "执行 llll 指令:" 45 llll 46 echo "执行返回的结果:$?"
结果:
可以看出:使用$*时同$@或"$@"没有差别,但"$*" 会将所有的参数看成一个整体,需小心使用。
7.简单的正则表达式
1) grep、正则表达式
grep(gloabal search regular expression and print out the line)
格式:grep [-option] [--color=auto] '需要检索的字符串(正则表达式)' filename
常用选项:
-a(all text):将二进制文件以文本形式的方式搜索数据
-c(count):计算找到 '需要检索的字符串(正则表达式)' 的次数
-i(ignore): 忽略大小写查询
-n(line - num):显示查找的行号
-v(invert-match):反向查询
测试文本:
1. 常用选项测试
2.添加正则表达式测试
先看一个简单的例子
[*]表示任意一个字符,上述的两个[a-zA-Z]即表示两个字符;
a-z:表示26个小写字母
A-Z:表示26个大写字母
a-zA-z:表示52个大小写字母
go[a-zA-Z][a-zA-Z]:表示匹配的字符串长度为4且前两个字符固定不变后两个字符必须为字母
基础正规表示法及范例:
正则表达式字符 |
意义及范例 |
^word(头) |
意义:待搜寻的字符串(word)在行首 例子:查询以ni(不区别大小写)为开头的那一行,并列出行号 grep -ni '^ni' test.txt |
word$(尾) |
意义:待搜寻的字符串在行尾 例子:查询以!为结尾的行,并列出行号 grep -ni '!$' test.txt |
. |
意义:表示任意字符(该位必须表示一个字节) 例子:查询以g开头的至少包含8个字符的那一行,并列出行号 grep -ni '^g.......' test.txt |
\ |
意义:转义字符 例子:查询包含’’(单引号的)那一行,并列出行号 grep -ni \'\' test.txt |
* |
意义:匹配0到无穷多个前一个字符 注意:因为可以是0个所以对于前面仅为单个字符(a*)的情况将全部返回 例子: 1、查询全部 grep -ni 'g*' test.txt (将输出全部文本,此时g可以任意字符)
2、查询以g或G开头的任意行 grep -ni "^gx*" test.txt(此时x可以是任意字符)
3、查询以gooo开头的任意行 grep -ni "^gooox*" test.txt(此时x可以是任意字符) |
[list] |
意义:[需要获取的字符] 例子:获取以g开头的行,并显示行号 grep -ni "^[g]" test.txt |
[n1-n2] |
意义:[需要获取的字符范围] 例子:获取以[A-Z]为开头的行,并显示行号 grep -n "^[A-Z]" test.txt |
[^list] |
意义:[非字符范围内的数据] 例子:获取以非[A-Z]为开头的行,并显示行号 grep -n "^[^A-Z]" test.txt |
\{n,m\} |
意义: 1、\{n,m\}至少连续n到m个的字符都是指定字符,n,m表示范围内的个数 例子:获取以g开头的,连续1-2个字符为’o’的行,(注意:超过个数的也是符合的行,小于的则不符合) grep -n "go\{1,2\}" test.txt
2、\{n,}至少连续n个字符都是指定字符,n表示最小个数 例子:获取以g开头 + 至少2个连续o + 以d!为结尾的行 grep -n "^go\{2,\}d\!$" test.txt
3、\{n\}指定n个指定字符(注意此时的n为固定个数,多于n或小于n都属于不符合的情况) 例子:获取以g开头 + 3个连续o + 以d!为结尾的行 grep -n "^go\{3\}d\!$" test.txt
|
2) sed(stream editor for filtering and transforming text)
命令格式: sed [option] 'command' [file]
sed的 command 类似于vi,vi属于文本编辑器,sed属于命令行编辑器,对象都是输入文本
常用option:
-n:使用安静模式,只有被处理的那行才会被打印出来
-e:直接在指令模式上进行sed动作编辑
-f:将要使用的sed动作写入到一个文件内,-f filename将执行filename内的sed动作
-i:对[file]的处理直接写进文件
常用command:
a:append
c\:replace 替换指定行
d:delete
i:insert
p:printf
s:replace,替换
实例:
3) awk
8.shell语法
1) 变量
2)流程控制
2.1 if/else
以一个简短的例子来说明:
1 #!/bin/sh 2 a=10 3 b=20 4 5 # 情景1:if..fi # 6 if [ $a = $b ] 7 then 8 echo "a和b相等" 9 fi 10 11 # 情景2:if..else..fi # 12 if [ $a = $b ] 13 then 14 echo "a和b相等" 15 else 16 echo "a和b不相等" 17 fi 18 19 # 情景3:if..elif..fi # 20 if [ $a = $b ] 21 then 22 echo "a和b相等" 23 elif [ $a-gt$b ] 24 then 25 echo "a大于b" 26 fi
3)函数
1.简单函数
2.带参函数
4)文件包含
9.附记:
1)Umask权限
2)Linux启动加载脚本流程初探
参考资料:
- http://www.imooc.com/u/279399/courses?sort=publish(视频)
- http://c.biancheng.net/cpp/view/6994.html
- http://www.92csz.com/study/linux/
- http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856896.html
- http://www.regexlab.com/zh/regref.htm
- https://msdn.microsoft.com/zh-cn/library/az24scfc(v=vs.110).aspx#