《Shell编程从入门到精通》张昊-chap1-8
缘起
- 20190314开始复习及学习吧;
- 张昊编著;
内容
目录 i(9/314)
- 全书11章
chap1 第1个Shell程序 1(13/334)
1.1、第一道菜
[echo.sh]
#!/bin/sh cd /tmp echo "hello world!"
- (1)每一行代码是啥意思;(2)如何运行程序?
1.2、如何运行程序
1.2.1 选婿:位于第一行的#!
- 匹配解释器。
- 解释器路径可以用
whereis bash
查。 自删除脚本
#!/bin/rm # 运行这个脚本时,什么也不会发生,只是删自已 WHATEVER=65 echo "This line will never print!" exit $WHATEVER #脚本不会在这退出
1.2.2 找茬:程序执行的差异
source echo.sh
时,改变了目录。
1.2.3 shell的命令种类
- (1)内建命令
- (2)shell函数
- (3)外部命令
- 要知道
source
执行的差异,不会创建子进程,直接在父进程中执行。
1.3、Linux Shell的变量
1.3.1、变量
测试全局变量和局部变量的适用范围
#!/bin/sh num=123 func1() { num=321 echo $num } Func2() { local num=456 #局部变量 echo $num } echo $num func1 echo $num func2 echo $num
1.3.2、用echo输出变量
echo
掌握各种转义字符
1.3.3、环境变量的相关操作
export
命令bash的启动文件/登出文件
/etc/profile
/etc/bashrc
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_logout
unset
命令env
命令
- 1.3.4、shell中的一些常用环境变量
1.4、Linux Shell是解释型语言
- 1.4.1、编译型语言和解释型语言
- 1.4.2、Linux Shell编程的优势
1.5、小结
chap2 shell编程基础 15(27/334)
2.1、向脚本传递参数
2.1.1、Shell脚本的参数
Shell编程中的函数
testfunc() { echo "$# parameters"; echo "$@"; }
shell编程中参数引用
0,1,2...
*
@
#
$
!
?
-
- 在
2.1.2、参数的用途
[ps.sh]
#! /bin/sh ps -eLf | grep $1
mv
和mkdir
命令
2.2、I/O重定向
2.2.1、标准输入、标准输出与标准错误
cat
命令后面的主要参数
2.2.2、管道与重定向
>
、<
、>>
、|
head
命令
- 2.2.3、文件描述符
2.2.4、特殊文件的妙用
/dev/null
/dev/zero
/dev/tty
read
命令,我基本没在命令中用过,最多编程中有用
2.3、基本文本检索
grep
相关命令
2.4、Unix/Linux系统的设计与shell编程
2.4.1、一切皆文件
- Linux文件的后缀名
- Linux文件类型
ls
命令
- 2.4.2、UNIX编程的基本原则
2.5、小结
chap3 编程的基本元素 39(51/334)
3.1、再识变量
- [variable.sh]
shell中有3种变量:
- 用户变量
- 位置变量:在对参数判断和命令返回值判断时使用。也叫系统变量
- 环境变量
- 3.1.1、用户变量
3.1.2、位置变量
- 也叫系统变量,直接引用只能$0~$9,超过要用括号,即
${10}
- [process.sh]
[Process2.sh]
#!/bin/sh if[ $# -ne 2 ]; then echo "Usage: $0 string file"; exit 1; fi grep $1 $2; if[ $? -ne 0 ]; then echo "Not Found \"$1\" in $2"; exit 1; fi echo "found \"$1\" in $2";
- 也叫系统变量,直接引用只能$0~$9,超过要用括号,即
- 3.1.3、环境变量
- 3.1.4、启动文件
3.2、函数
- 当shell执行函数时,并不独立创建子进程。
- shell执行命令的顺序
- 函数的使用规则
- 自动加载
3.2.1、函数定义
unset -f funcname
删除函数[user_login.sh]
#!/bin/bash function user_login() { if who | grep $1 >/dev/null then echo "User $1 is on." else echo "User $1 is off." fi }
3.2.2、函数的参数和返回值
[演示函数的返回值]
#! /bin/bash add() { let "sum=$1+$2" return $sum }
3.3、条件控制与流程控制
- 3.3.1、if/else语句
3.3.2、退出状态
$?
返回上一条语句的退出状态退出状态值
- 0:成功
>0
:在重定向或单词展开期间()失败- 1~125:退出失败
- 126:命令找到,但无法执行命令文件
- 127:命令无法找到
>128
:命令因收到信号而死亡
- 3.3.3、退出状态与逻辑操作
- 3.3.4、条件测试
3.4、循环控制
- 3.4.1、for循环
3.4.2、while/until循环
[遍历PATH路径]
path = $PATH while [ -n $path ]; do ls -ld ${path%%:*} #ls -ld显示path的第一个目录 path = ${path#*:} #截去path中第一个目录和冒号 done
3.4.3、跳出循环
break
3.4.4、循环实例
- [例3.17 命令行参数处理]
[例3.18 getopt的使用]
author=false list=false file="" while getopt alf: opt do case $opt in f) file=$OPTARG #将-f参数的下一个参数截取至file变量 ;; l) list = true ;; a) author = true ;; esac done shift ${{OPTIND - 1}} #删除选项,留下参数
getopt
分析命令行标志和参数
3.5、小结
chap4 正则表达式 66(78/334)
grep、sed、awk、more、vi
4.1、什么是正则表达式
- 4.1.1 正则表达式的广泛应用
4.1.2 如何学习正则表达式
- 读例子;理解后再修改和实践
4.1.3 如何实践正则表达式
- 不断修改、测试
4.2、正则基础
4.2.1 元字符
都支持的meta字符
^
:锚定行或字符串的开始$
:锚定行或字符串的结束.
*
[...]
\
- 不同的meta字符
- grep程序支持的meta字符plus
4.2.2 单个字符
- 一般字符
- 转义的meta字符
- .(点号)字符
- 方括号表达式
- 4.2.3 单个表达式匹配多个字符
- 4.2.4 文本匹配锚点
- 4.2.5 运算符优先级
4.2.6 更多差异
- 后向引用
- 分组
- 交替
4.3、正则表达式的应用
4.3.1、扩展
- ed命令的演化成grep和sed
- [例4.9 单词的开头结尾匹配]
- GNU支持的额外正则表达式运算符
4.3.2 案例研究:罗马数字
- [例4.11 检验百位数]
- 4.3.3 案例研究:解析电话号码
4.4、小结
chap5 基本文本处理 87(99/334)
sort、uniq、cut、join、head、tail、grep、wc、fmt、fold、pr、tr
5.1、排序文本
5.1.1、sort命令的行排序
- 例5.1 使用sort命令按照ASCII顺序排序文本
sort file.txt
- 例5.2 字典序
sort -d file.txt
- 例5.3 忽略大小写差异
sort -d -f file.txt
- 例5.1 使用sort命令按照ASCII顺序排序文本
5.1.2、sort命令的字段排序
sort -t: -k3 -n /etc/group
5.1.3、sort小结
- 例5.5 sort命令不稳定性演示
5.2、文本去重
uniq
5.3、统计文本行数、字数以及字符数
wc
5.4、打印和格式化输出
- 5.4.1、使用pr打印文件
- 5.4.2、使用fmt命令格式化文本
- 5.4.3、使用fold限制文本宽度
5.5、提取文本开头和结尾
head
与tail
5.6、字段处理
- 5.6.1、字段的使用案例
- 5.6.2、使用cut取出字段
- 5.6.3、使用join连接字段
5.6.4、其他字段处理方法
awk
5.7、文本替换
- 5.7.1、使用tr替换字符
5.7.2、其他选择
sed、awk、perl、python
5.8、一个稍微复杂的例子
- 5.8.1、实例描述
- 5.8.2、取出记录的ip字段和id字段
- 5.8.3、将记录按照ip顺序排序
- 5.8.4、使用uniq统计重复ip
- 5.8.5、根据访问次数进行排序
- 5.8.6、提取出现次数最多的100条
5.9、小结
chap6 文件和文件系统 118(130/334)
ls、cat、chown、chgrp、chmod、umask、mkdir、touch、find、xargs、comm、diff、vimdiff、fdisk、mkfs、df、mount
6.1、文件
- 6.1.1、列出文件
- 6.1.2、文件的类型
6.1.3、文件的权限
chown
和chgrp
,以及chmod
6.1.4、文件的修改时间
- 用
touch
更新文件的访问和修改时间
- 用
6.2、寻找文件
- 6.2.1、find命令的参数
6.2.2、遍历文件
[例6.10 xargs使用]
find /tmp -type f -print | xargs file
6.3、比较文件
6.3.1、使用comm比较排序后文件
comm file1 fiel2
- 6.3.2、使用diff比较文件
6.3.3、其他文本比较方法
vimdiff
6.4、文件系统
- 6.4.1、什么是文件系统
- 6.4.2、文件系统与磁盘分区
- 6.4.3、linux分区格式的选择与安全性
- 6.4.4、文件系统与目录树
- 6.4.5、文件系统的创建与挂载
6.5、小结
chap7 流编辑 155(167/334)
7.1、什么是sed
7.1.1 挑选编辑器
- VI是交互式编辑器。
- sed是流编辑器,可以对从管道这样的标准输入接收的数据进行编辑。
7.1.2 sed的版本
sed --version
7.2、sed示例
7.2.1 sed的工作方式
- sed是基于行的,不修改任何输入文件,将结果写入标准输出(stdout)。
sed -e 'd' /tmp/passwd.bak
# d是删除,全部删除sed -e '5d' /tmp/passwd.bak
# 删除第5行
- 7.2.2 sed工作的地址范围
- 7.2.3 规则表达式
7.3、更强大的sed功能
7.3.1 替换
sed -e 's/power/jiechen/g' /tmp/a.c
#s是替换,g是全局
- 7.3.2 地址范围的迷惑
7.4、组合命令
7.4.1 组合多条命令
sed -n -e '=;p' /tmp/passwd.piece
- 7.4.2 将多条命令应用到一个地址范围
7.5、实际的例子
sed -e 's/$/\r/' myunix.txt > mydos.txt
7.6、sed实践 167
- 7.6.1 第一步 替换名字
- 7.6.2 第二步 删除前3行
- 7.6.3 第三步 显示5~10行
- 7.6.4 第四步 删除包含lane的行
- 7.6.5 第五步 显示生日在november-december之间的行
- 7.6.6 第六步 把3个星号(*)添加到以fred开头的行
- 7.6.7 第七步 用jose hasretired取代包含jose的行
- 7.6.8 第八步 把popeye的生日改成11/14/46
- 7.6.9 第九步 删除所有空白行
- 7.6.10 第十步 脚本
7.7、小结
chap8 文本处理利器awk 176(188/334)
8.1、来个案例
awk '{print $0}' /etc/fstab
# print $0是打印整行,print和print $0效果是一样的- awk常常用于处理字段,我个人理解为列处理
8.2、基本语法
- 8.2.1 多个字段
8.2.2 使用其他字段分隔符
awk -F ":" '{print "USER: "$1 "\tSHELL: "$7}' /tmp/passwd.piece
- ‘-F’设置的是awk的初始化变量FS,FS默认的字段分格符是空白字符,现在改成冒号
8.3、awk语言特性
- 8.3.1 awk代码结构
- 8.3.2 变量与数组
- 8.3.3 算术运算和运算符
- 8.3.4 判断与循环
- 8.3.5 多条记录
8.4、用户自定义函数
- 8.4.1 自定义函数格式
- 8.4.2 引用传递和值传递
- 8.4.3 递归调用
8.5、字符串与算术处理
- 8.5.1 格式化输出
- 8.5.2 字符串函数
- 8.5.3 算术函数
8.6、案例分析
- 8.6.1 生成数据报表
- 8.6.2 多文件联合处理
- 8.6.3 检验passwd格式的正确性
- 8.6.4 sed/awk单行脚本
8.7、小结 222
收获
履历
20190314过了一遍chap1和2,还是有一些知识点不知道的。
- shell中的参数引用就不熟。
20190315过了一遍chap3-5。
- chap03来看,还是自已读、写shell有点少,语法有些点不懂外,写得就更少,要从基础的实践一下,觉得门入得还不深。
- chap04正则基本都会用到,但各种细节和元字符并没有完全了解。
- 毕竟没有处理过文本,chap5里的命令大部分是我没有接触的,更没说对参数的了解了,但基本上属于一讲还是能懂的啊。
20190316过了一遍chap6
- find里的xargs参数;以及comm命令,我用得确实不多。
20190318过了一遍chap7、08
- 熟悉了一下sed的各个参数,例子场景不错,但我还没有实践呢。
- chap08只是简单看看,原来'awk'还可以自成函数,这个反正是不记得了,不清楚以前看没看过呢。awk要好好学学