shell编程基础
Shell编程用途广泛,不管是做运维的还是做数据挖掘模型,日常的一些工作中都能用到它,如定时跑模型,取数据等等。在网易云课堂中发现北大青鸟的Linux Shell脚本应用课程,11个短视频,讲的很基础,例子也举的很多,很适合入门,本文作为一个课堂记录了,详细视频可以观看官网的视频,地址是http://study.163.com/course/courseMain.htm?courseId=306001#/courseMain,下图是视频所要讲的内容。
![](http://images0.cnblogs.com/i/568636/201402/271926003102564.png)
一 初始shell
1,什么是shell?介于内核跟用户之间的解释程序,命令解释器,翻译官
2,什么是脚本?一类使用特定语言,按预设顺序执行的文件,批处理、宏解释性程序(python,ruby,js,php,shell,asp)
3,创建第一个shell脚本?
命令行:
useradd zhangsan
passwd zhangsan
shell脚本:
#!/bin/bash
useradd zhangsan
echo 123456 | passwd --stdin zhangsan
4,执行shell脚本?
1) chmod +x ***.sh
./***.sh
2) sh ***.sh
3) source ***.sh
二 组合命令
find /etc -name "*.conf" -type f
在/etc文件下下找后缀为.conf文件,输出打印在控制台上
find /etc -name "*.conf" -type f | wc -l
加一个 | 管道命令 后面接着wc -l之后 ,这样会执行完前一个命令,紧接着执行第二个命令,就会显示在/etc文件目录下,后缀为.conf文件的个数
![](http://images0.cnblogs.com/i/568636/201402/271926145807990.png)
逻辑关系
与(&&),或(||),顺序执行(;)
echo "萝卜" && echo "青菜"
输出:萝卜
青菜
echo "萝卜" || echo "青菜"
输出:萝卜
三 变量
变量基本操作
定义及赋值:变量名=变量值 title=beida
引用变量:变量名,{变量名} echo $title 输出 “beida”
双引号:允许引用、\转义 echo "$title" 输出 beida
单引号:禁止引用、\转义 echo '$title' 输出 $title
反撇号:echo `uname -r` 或者 DATE=`date -d '1 days ago' +"%Y-%m-%d"` ; ` `跟$()一样的功能
下图是运行结果
![](http://images0.cnblogs.com/i/568636/201402/271934177612206.png)
$?:表示前一条命令的状态,0正常,非0异常
$0:脚本自身的程序名
1−9:第1-第9个位置参数
$*:命令行的所有位置参数的内容
$#:命令行的位置参数个数
例子:![](//images0.cnblogs.com/i/568636/201402/271926336529518.png)
![](http://images0.cnblogs.com/i/568636/201402/271926336529518.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271926441712098.png)
![](http://images0.cnblogs.com/i/568636/201402/271926441712098.png)
四 数值运算及处理
变整数运算操作
格式1:expr 数值1 操作符 数值2
格式2:$[数值1 操作符 数值2]
例子:![](//images0.cnblogs.com/i/568636/201402/271936273286989.png)
注意乘号的表达式,*在shell里面是通配符,要用\转义
![](http://images0.cnblogs.com/i/568636/201402/271936273286989.png)
![](http://images0.cnblogs.com/i/568636/201402/271936340445408.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271936551158280.png)
![](http://images0.cnblogs.com/i/568636/201402/271936551158280.png)
几个数值处理技巧
变量递增 :let 变量名++、 let 变量名--
例子:![](//images0.cnblogs.com/i/568636/201402/271937072377847.png)
![](http://images0.cnblogs.com/i/568636/201402/271937072377847.png)
使用随机数 :RANDOM 变量 (0-32767)
例子:![](//images0.cnblogs.com/i/568636/201402/271937170661055.png)
![](http://images0.cnblogs.com/i/568636/201402/271937170661055.png)
生成数字序列:seq 首数 末数、seq 首数 增量 末数 跟R语言的操作还不一样(a<- seq(首数,末数,增量))
例子:![](//images0.cnblogs.com/i/568636/201402/271937362708854.png)
seq 3默认从1开始,3为末数
![](http://images0.cnblogs.com/i/568636/201402/271937362708854.png)
![](http://images0.cnblogs.com/i/568636/201402/271937462973347.png)
小数运算操作
![](http://images0.cnblogs.com/i/568636/201402/271938528663054.png)
五 字符串处理
子串截取操作
路径分割:dirname 命令 、basename命令
例子:![](//images0.cnblogs.com/i/568636/201402/271941564743149.png)
![](http://images0.cnblogs.com/i/568636/201402/271941564743149.png)
使用expr命令:expr substr $var1 起始位置 截取长度
例子:![](//images0.cnblogs.com/i/568636/201402/271942149334618.png)
![](http://images0.cnblogs.com/i/568636/201402/271942149334618.png)
使用${var1:起始位置:截取长度}
例子:![](//images0.cnblogs.com/i/568636/201402/271942221031811.png)
![](http://images0.cnblogs.com/i/568636/201402/271942221031811.png)
字符串替换操作
例子:
/old/new 把字符串第一个old换成new,//old/new 把字符串所有的old换成new
![](http://images0.cnblogs.com/i/568636/201402/271942445273427.png)
使用随机字符串
![](http://images0.cnblogs.com/i/568636/201402/271944055591915.png)
![](http://images0.cnblogs.com/i/568636/201402/271944146325721.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271944234469214.png)
![](http://images0.cnblogs.com/i/568636/201402/271944234469214.png)
六 条件测试
测试操作规范
格式1:test 条件表达式
格式2:[条件表达式]
[条件表达式] && echo yes
例子:
可以看到/etc/grub 不是文件或目录,所以[ -d "/etc/grub" ] 是错误的。
![](http://images0.cnblogs.com/i/568636/201402/271946408404387.png)
文件状态的检测
-e:目标是否存在;-d:是否是目录;-f:是否是文件
例子:![](//images0.cnblogs.com/i/568636/201402/271946565341814.png)
![](http://images0.cnblogs.com/i/568636/201402/271946565341814.png)
例子中要注意[跟-f之间有空格的
例子:![](//images0.cnblogs.com/i/568636/201402/271948091085554.png)
![](http://images0.cnblogs.com/i/568636/201402/271948091085554.png)
整数值比较、字符串匹配
![](http://images0.cnblogs.com/i/568636/201402/271948318749741.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271948415818906.png)
![](http://images0.cnblogs.com/i/568636/201402/271948415818906.png)
![](http://images0.cnblogs.com/i/568636/201402/271948491357982.png)
七 使用if判断结构
程序流控制
单分枝、双分支的if应用
单分支
if 条件测试
then 命令序列
fi
例子:![](//images0.cnblogs.com/i/568636/201402/271949086102799.png)
![](http://images0.cnblogs.com/i/568636/201402/271949086102799.png)
双分支
if 条件测试
then 命令序列1
else 命令序列2
fi
例子:![](//images0.cnblogs.com/i/568636/201402/271949194096163.png)
![](//images0.cnblogs.com/i/568636/201402/271949268039724.png)
![](http://images0.cnblogs.com/i/568636/201402/271949194096163.png)
![](http://images0.cnblogs.com/i/568636/201402/271949268039724.png)
多重分值的if应用
双分支
if 条件测试
then 命令序列1
elif 条件测试
then 命令序列2
.....
else 命令序列n
fi
例子:![](//images0.cnblogs.com/i/568636/201402/271949527943430.png)
![](//images0.cnblogs.com/i/568636/201402/271950001189435.png)
![](http://images0.cnblogs.com/i/568636/201402/271949527943430.png)
![](http://images0.cnblogs.com/i/568636/201402/271950001189435.png)
八 使用for循环
for语句结构
格式: for 变量名 in 取值列表
do
命令序列
done
基本用法示范
例子:![](//images0.cnblogs.com/i/568636/201402/271952339659435.png)
![](http://images0.cnblogs.com/i/568636/201402/271952339659435.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271952422321829.png)
![](http://images0.cnblogs.com/i/568636/201402/271952422321829.png)
案例实战
例子:![](//images0.cnblogs.com/i/568636/201402/271953247012903.png)
![](//images0.cnblogs.com/i/568636/201402/271953289181891.png)
![](http://images0.cnblogs.com/i/568636/201402/271953247012903.png)
![](http://images0.cnblogs.com/i/568636/201402/271953289181891.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271953363881939.png)
![](//images0.cnblogs.com/i/568636/201402/271953406519643.png)
![](http://images0.cnblogs.com/i/568636/201402/271953363881939.png)
![](http://images0.cnblogs.com/i/568636/201402/271953406519643.png)
九 使用case分支
case语句结构
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
.....
*)
默认命令序列
esac
由于在shell里面分号(;)算是命令分隔符,所以case 结构里面用两个分号(;;)
基本用法示范
例子:![](//images0.cnblogs.com/i/568636/201402/271954567682528.png)
![](http://images0.cnblogs.com/i/568636/201402/271954567682528.png)
案例实战
例子:![](//images0.cnblogs.com/i/568636/201402/271955051006178.png)
![](//images0.cnblogs.com/i/568636/201402/271955129013026.png)
![](//images0.cnblogs.com/i/568636/201402/271955190122858.png)
![](http://images0.cnblogs.com/i/568636/201402/271955051006178.png)
![](http://images0.cnblogs.com/i/568636/201402/271955129013026.png)
![](http://images0.cnblogs.com/i/568636/201402/271955190122858.png)
例子:![](//images0.cnblogs.com/i/568636/201402/271955259269805.png)
![](http://images0.cnblogs.com/i/568636/201402/271955259269805.png)
十 awk文本处理工具
关于文本处理
shell输出是文本
非交互式处理方式:1)重定向、管道、命令替换;2)head、more、cut、tr;3)grep、awk、sed
awk基本命令格式
awk '模式 {操作}' 文件1 文件2
awk 'NR==1 {print}' /etc/hosts #'第一行 {打印}'
![](http://images0.cnblogs.com/i/568636/201402/271956549649372.png)
常见用法示例
例子:准备文件![](//images0.cnblogs.com/i/568636/201402/271957147171273.png)
![](http://images0.cnblogs.com/i/568636/201402/271957147171273.png)
按行号输出文本![](//images0.cnblogs.com/i/568636/201402/271957214006150.png)
![](http://images0.cnblogs.com/i/568636/201402/271957214006150.png)
使用比较运算![](//images0.cnblogs.com/i/568636/201402/271957258622911.png)
![](http://images0.cnblogs.com/i/568636/201402/271957258622911.png)
使用正则运算![](//images0.cnblogs.com/i/568636/201402/271957320198229.png)
![](http://images0.cnblogs.com/i/568636/201402/271957320198229.png)
指定输出![](//images0.cnblogs.com/i/568636/201402/271957409875765.png)
![](http://images0.cnblogs.com/i/568636/201402/271957409875765.png)
十一 sed文本处理工具
sed基本用法
语法格式:
sed '编辑指令' 文件1 文件2 ...
sed -n '编辑指令' 文件1 文件2 ...
sed -i '编辑指令' 文件1 文件2 ...
![](http://images0.cnblogs.com/i/568636/201402/271957518884929.png)
编辑指令的写法
格式:[地址1[,地址2]] 操作类型
多条指令之间以分号隔开
例如 sed -n '3p;5p' /etc/hosts
![](http://images0.cnblogs.com/i/568636/201402/271957581661749.png)
输出文本
例子:准备![](//images0.cnblogs.com/i/568636/201402/271959171762121.png)
![](http://images0.cnblogs.com/i/568636/201402/271959171762121.png)
隔行输出文本![](//images0.cnblogs.com/i/568636/201402/271959217004368.png)
![](http://images0.cnblogs.com/i/568636/201402/271959217004368.png)
注释: 先p后n 先打印一行,然后忽略一行,接着循环。。
正则操作![](//images0.cnblogs.com/i/568636/201402/271959299898302.png)
![](http://images0.cnblogs.com/i/568636/201402/271959299898302.png)
注释:'/w2k8/,p' #首先查找包含w2k8的首行,p是最后一行
删除文本![](//images0.cnblogs.com/i/568636/201402/271959406872167.png)
![](http://images0.cnblogs.com/i/568636/201402/271959406872167.png)
删除不符合条件文本
!d表示 不删除
![](http://images0.cnblogs.com/i/568636/201402/271959449798114.png)
替换文本
第3,4行的hunter 替换成BADBOY 后面的/g 是所有的包含hunter
![](http://images0.cnblogs.com/i/568636/201402/271959537791135.png)
![](http://images0.cnblogs.com/i/568636/201402/272000006322596.png)
ter换成空串
分类: 杂记