Much thanks to Classic Shell Scripting
#chapter 2 shell basic
1. 访问脚本从命令行接收到的参数:$n
在脚本中使用 $1 访问第一个参数,$2访问第二个,当超过9时,用大括号引起来,如 ${10}。
2. 在shell脚本执行时,使用-x打开脚本执行跟踪功能。如: $ sh -x nusers.sh
3. 列出系统所支持的所有语言: locale -a
#chapter 3 search and substitution
4. shell BRE(Basic RE) and ERE(Extended RE)正则表达式简记:
\ 关闭或者打开后续字符的特殊意义
. 匹配任何单个字符,初NUL外
* 匹配在它之前的任何数目的单个字符
+ 1个或多个(ERE only)
? 0个或多个(ERE only)
^ 表示一行的开始,在[^...]里面表示取反
$ 表示一行的结尾
[...] 匹配方括号内的任一单个字符
{n} 匹配前面单个字符出现n次(ERE,在BRE中需要使用转义\{n\})
{n,m} 出现至少n次,最多m次
() 表示一个实例(ERE only)
| 匹配之前或之后的正则表达式(ERE only)
注意:在BRE下,^$只在起始和结束处具有特殊意义,在其他位置如39.8$killo就表示$本身。
5. 向后引用: backreferences
如,\(ab\)\(cd\)[def]*\2\1 可以匹配abcdcdab, abcdeeecdab, abcdffcdab, ...向后引用最多可以有9个
6. POSIX字符集: [:alpha:]
[:alnum:] 数字字符,如123
[:alpha:] 字母字符,如abcDEF
[:lower:] 小写字母字符,如abc
[:upper:] 大写字母字符,如DEF
[:blank:] 空格space于定位tab字符
……更多
$ grep -E ^[[:alpha:]]\{3\} data.txt
hello, world.
abcDEFdefABC
7. ERE(Extended RE)
没有向后引用。
区间表达不需要\{\},直接使用abc{3,5},表示c出现3到5次
? 表示0个或一个前置RE
+ 1个或多个
* 与BRE相同,0个或多个
| 交替,匹配这个序列或那个序列或... read|write|listen
() 分组,(abc){3,5}表示abc出现3到5次,但不包括括号()本身,
8. 额外的GNU正则表达式运算符: \w
\w 匹配任何单词组成的字符
\W 匹配任何非单词组成的字符,^\w
9. 进行文本查找替换: sed(steam editor)
sed s/regexp/replacement/
$ sed 's/:.*/:******/' data.txt
hello, world.
abcDEFdefABC
password:******
another password:******
上面命令把冒号(:)后面的所有内容替换成6个星号(*),sed s/regexp/replacement/中的/作为一个定界符,任何可以显示的字符都可以,如
sed s;regexp;replacement;
sed s:regexp:replacement:
sed s,regexp,replacement,
……等
$ find /home/owen/test/todelete/ -type d -print |
sed 's;/home/owen/test/todelete;/home/owen/test/todel;' |
sed 's/^/mkdir /' |
sh -x
+ mkdir /home/owen/test/todel/
+ mkdir /home/owen/test/todel/xyz
该命令首先找出/home/owen/test/todelete/这个目录下的所有目录,包括这个目录自身,然后把todelete替换成todel,得到如下结果:
/home/owen/test/todel/
/home/owen/test/todel/xyz
然后在每行前面加上"mkdir "命令创建新的目录。所实现的功能类似cp。
10. 查看系统的密码信息: /etc/passwd
$ more /etc/passwd
owen:x:1000:1000:owen,,,:/home/owen:/bin/bash
每行都是以:分隔的7个字段,分别表示
owen 用户名称
x 加密后的密码
1000 用户ID编号
1000 用户组ID编号
owen,,, 用户姓名,附加其他信息,如联系方式等
/home/owen 用户的根目录
/bin/bash 登录的shell类型
11. 从文本中剪贴部分内容: cut
$ cut -d : -f 1,5 /etc/passwd | grep -E ^m
man:man
mail:mail
messagebus:
mysql:MySQL Server,,,
-d 表示分割符,-f 表示field
12. 连接2个文件,基于字段:join
join quotas.sorted sales.sorted
使用两个文件中第一个字段进行连接,如
quotas.sorted
a b
sales.sorted
a c
连接之后,为a b c
当然可以指定连接的key, -1 2 -2 5, 参考manual
13. 重新编排字段: awk
$ ls -l | awk '{ print $8, $5, $1}' | sort
data.txt 67 -rw-r--r--
finduser 88 -rwxr-xr-x
merge-sales.sh 363 -rwxr-xr-x
note.sh 36 -rwxr-xr-x
nusers 60 -rwxr-xr-x
quotas 58 -rw-r--r--
sales 71 -rw-r--r--
total
这里先列出当前目录下的文件,然后使用awk显示文件名,大小,权限,最后进行排序显示。
awk默认使用空格作为分隔字符。
$ ls -l | awk '{ printf "%s %s\t %s\n", $1, $5, $8}' | sort
其基本模式如下:
#chapter 4 text process tools
14. 文本排序: sort
$ sort -t : -k 3,3 /etc/passwd
-t指定分隔符,-k指定从哪个字段到哪个字段作为key进行排序
15. 去除重复: uniq
$ sort uniq-data | uniq -c
2 duo
3 tres
1 unus
消除重复,可以控制显示重复的或是未重复的记录
16. 简单的文本格式化命令: fmt
$ more data.txt | fmt -w 50
hello, world. abcDEFdefABC password:123456
another password:666888
string sort\nbased on lines delimilated by new
line sign
格式化成每行最多50个字符
17. 计算行数、字数和字符数: wc
/usr/share/dict$ more words | grep ^herb | wc -lwc
17 17 165
18. 查看标准输入的前n条记录,或是文件列表中的前n条,或后n条: head, tail
head -n 5 /etc/passwd
sed -e 5q /etc/passwd
显示倒数n条,一般用来查看最近的日志记录
tail -n 5 /etc/passwd
#chapter 5 the magic power of pipe
19. 文字解谜好帮手puzzle-help.sh文件: example
FILES="
/usr/dict/words
/usr/share/dict/words
"
pattern="$1"
egrep -h -i "$pattern" $FILES 2> /dev/null | sort -u -f
使用这个脚本来进行查找具有10个字母的单词,以b开头,第7位不是x就是y:
$ sh puzzle-help.sh '^b.{5}[xy].{3}$' | fmt
beatifying Birdseye's blarneying Brooklyn's Bulawayo's
等价于使用命令:
/usr/share/dict$ more words | egrep -i '^b.{5}[xy].{3}$'| sort
beatifying
Birdseye's
blarneying
Brooklyn's
Bulawayo's
20. 转换或者删除字符:tr
tr [ options ] source-char-list replace-char-list
-c 取source-char-list的反义,即对没有出现在source-char-list中的字符进行转换或删除
-d 删除source-char-list里出现的字符,如删除所有元音字母:
echo hello world | tr -d [aeiou]
hll wrld
-s 浓缩重复的字符,如:
echo hello world | tr -s l
helo world
一般会组合来使用,如全部转换成小写字符,所有非字母字符转换成换行符号
echo heLLo WorLd 123 End | tr A-Z a-z | tr -cs A-Za-z '\n'
hello
world
end
这里没有包括数字,如果需要包括,则添加A-Za-z0-9就可以了
21. 统计一篇文章中单词出现频率: wf
tr -cs A-Za-z0-9 '\n' | 将非字母字符转换成换行符号,-cs参考第20条笔记
tr A-Z a-z | 全部转换成小写字母
sort | 排序
uniq -c | 统计频率,结果: 13 the等
sort -k1,1nr -k2 | 首先只取第一个field即数字,按照数字顺序-n逆序-r排序,再对单词以字典顺序排序
sed ${1:-25}q ${1}获取命令行的第一个参数,如果没有默认为25,后面q表示退出程序
${1:-25}是shell里面的一个参数展开形式,具体如下:
${var:-default-var}
展开方式是:首先查找${var},如果找到,值就为${var},如果没有找到,值就等于default-var
使用(需要chmod +x wf,然后把wf放到$PATH路径下),使用频率最高的:
man awk | wf | pr -c4 -t -w80
292 the 69 are 50 0 40 mawk
169 and 69 string 49 s 40 n
168 is 65 1 48 expr 39 be
155 a 64 if 45 as 38 awk
124 of 52 for 45 or 38 file
118 to 52 with 40 an 38 i
80 in
pr命令,打印格式化,page column for printing
-c4 表示column4,相当于word的分栏操作,这里设置为4栏
-t 表示不显示页头和页尾,如果没有这个,就是一张打印纸那么大
-w80 设置页面宽度,这里是80个字符
最低的呢:
$ man awk | wf 99999 | tail -n 25 | pr -c4 -t -w80
1 typically 1 under 1 values 1 wc
1 u 1 underscores 1 variations 1 we
1 unaltered 1 unlike 1 variety 1 whidbey
1 unambiguous 1 unnecessary 1 vdiesp 1 writing
1 unbuffered 1 unsafe 1 vertical 1 xaxbxcx
1 unchanged 1 usually 1 via 1 xhh
1 undefined
我的path
echo $PATH
/home/owen/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
这个程序比较有意思,我们可以算出awk手册里使用了多少个不重复的单词,才1014个,99999这个数没有实际意义,只是很大而已
$ man awk | wf 99999 | wc -l
1014
高频词汇(频率在5次以上,包括5次)个数,尽然是这么得少!
$ man awk | wf 99999 | awk '$1 >= 5' | wc -l
220
22. 学以致用: 标记和自动目录生成
$ more shell笔记.txt | grep -E '#'
#chapter 2 shell basic
#chapter 3 search and substitution
#chapter 4 text process tools
#chapter 5 the magic power of pipe
more shell笔记.txt | grep -E '^[0-9]+\.' | sed 's/^/@-/'
@-1. 访问脚本从命令行接收到的参数:$n
@-2. 在shell脚本执行时,使用-x打开脚本执行跟踪功能。如: $ sh -x nusers.sh
@-3. 列出系统所支持的所有语言: locale -a
@-4. shell BRE(Basic RE) and ERE(Extended RE)正则表达式简记:
@-5. 向后引用: backreferences
@-6. POSIX字符集: [:alpha:]
@-7. ERE(Extended RE)
@-8. 额外的GNU正则表达式运算符: \w
@-9. 进行文本查找替换: sed(steam editor)
@-10. 查看系统的密码信息: /etc/passwd
@-11. 从文本中剪贴部分内容: cut
@-12. 连接2个文件,基于字段:join
@-13. 重新编排字段: awk
@-14. 文本排序: sort
@-15. 去除重复: uniq
@-16. 简单的文本格式化命令: fmt
@-17. 计算行数、字数和字符数: wc
@-18. 查看标准输入的前n条记录,或是文件列表中的前n条,或后n条: head, tail
@-19. 文字解谜好帮手puzzle-help.sh文件: example
@-20. 转换或者删除字符:tr
@-21. 统计一篇文章中单词出现频率: wf
@-22. 学以致用: 标记和自动目录生成
使用sed命令给每条数据添加一个@-前缀,以便与真正的目录混淆。
#chapter 6 variables, repetitions
23. 设置或修改环境变量: export
PATH=$PATH:/home/owen/bin
export PATH
打印环境变量export -p
24. 从shell中删除变量于函数: unset
$ foo=123
$ echo $foo
123
$ unset foo
$ echo $foo
使用unset -f function_name删除函数,默认为-v即删除变量
25. 参数展开: ${varname:-word}
替换运算:
${varname:-word} 如果varname存在且非Null,则返回其值;否则返回word。用途: 如果变量未定义,则使用默认值
${varname:=word} 如果varname存在且非Null,则返回其值;否则设置它的值为word,并返回其值。用途: 如果变量未定义,则设置变量为默认值
${varname:+word} 如果varname存在且非Null,则返回word;否则返回null。用途: 为测试变量的存在。
${varname:?message} 如果varname存在且非Null,则返回其值;否则显示varname:message,并退出当前命令或脚本。用途: 捕捉由于变量未定义所导致的错误
$ echo ${vars:?"undefined, pls check it"}
bash: vars: undefined, pls check it
注意上面的${varname:-word}每个冒号(:)都是可选的,如果没有冒号,条件变为“如果varname存在”,也就是可以为空
更多模式匹配
$ p=/home/jwu/cases/long.file.name
$ echo $p
/home/jwu/cases/long.file.name
${variable#pattern} 如果模式匹配于变量的开头处,则删除匹配的最短部分,返回剩下的部分
$ echo ${p#/*/}
jwu/cases/long.file.name
${variable##pattern} 如果模式匹配于变量的开头处,则删除匹配的最长部分,返回剩下的部分
$ echo ${p##/*/}
long.file.name
${variable%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最短部分,返回剩下的部分
$ echo ${p%.*}
/home/jwu/cases/long.file
${variable%%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最长部分,返回剩下的部分
$ echo ${p%%.*}
/home/jwu/cases/long
注意,这里使用的pattern,以及shell里其他的地方,如case语句等,不同于前面正则表达式的模式匹配。如上,这里*代表任何一个符号,而.只代表点号本身。
26. POSIX标准化字符从长度运算符: ${#variable}返回$variable值的长度
$ d=diversification
$ echo $d
diversification
$ echo ${#d}
15
27. shell特殊变量,访问参数: $#, $@, $*
设置参数: $ set -- hello "hi there" greeting
$# 传递到shell脚本或函数的参数总数
$@ 传递进来的命令行参数,置于双引号("")内,会展开为个别的参数
$ for i in $@
> do echo i is $i
> done
i is hello
i is hi
i is there
i is greeting
注意上面的hi there之间的空格丢失了
$ for i in "$@"
> do echo i is $i
> done
i is hello
i is hi there
i is greeting
加上""会得到每个参数
$* 传递进来的命令行参数,置于双引号("")内,会展开为一个单独的参数
28. shell运算符与C语言类似: + - * /
运算置于$((...))之内,注意是圆括号
具体参考运算表
例:
$((3 && 2))
1
$ echo $((3 > 2))
1
$ echo $((3 > 4))
0
$ echo $(( (3 > 2) || (3 > 4) ))
1
与C及其衍生语言C++, Java, and awk等相同,非0值表示true。
29. 退出状态: $?
$ echo hello
hello
$ echo $?
0
$ e s
e: command not found
$ echo $?
127
POSIX的结束状态
0 命令成功退出
其他状态都是失败退出,如
127 命令找不到
可以在shell脚本中传递一个退出值给它的调用者,如exit 42
30. 判断语句: if-elif-else-fi
if pipeline
then ...
elif pipeline
then ...
else ...
fi
31. 逻辑判断: NOT, AND, OR
NOT if ! (...)
AND (...) && (...)
OR (...) || (...)
32. test命令: if...
if [ $# -ne 1 ]
then
echo Usage: finduser username >&2
exit 1
fi
主要的数字比较有
-eq equal
-ne not equal
-lt less than
-gt great than
-le less or equal
-ge great or equal
#chapter 7 input/output, file, and commands execute
to be continue...
分享到:
相关推荐
本文将基于《LINUX与UNIX SHELL编程指南》这本书的读书笔记,深入探讨Linux与Unix Shell编程的核心知识点。 一、Shell概述 Shell是一个命令解释器,它接收用户输入的命令并执行。在Linux和Unix系统中,常见的Shell...
如果你希望深入学习,可以阅读《The Linux Command Line》等经典书籍,或者参考CSDN博客上的"一起回顾一下linux常用命令 - sunxing007的专栏"等在线资源,如uuu.rar中可能包含的相关教程或笔记。 记住,Linux命令行...
Linux是开源的操作系统,它的命令行界面,尤其是Shell编程...因此,无论你是技术小白还是希望进一步提升,这份“Linux零基础学习笔记 Shell编程-菜鸟入门”都会是你宝贵的资源。祝你在学习的道路上越走越远,不断进步!
描述:这是一份综合的Linux Shell编程笔记,适用于想要学习或加强对Linux操作系统下Shell脚本编程的理解的人。该笔记包含了Shell脚本的基础知识、常用命令和技巧,以及实际的编程示例和案例。无论您是初学者还是有...
本文整理了一份Linux shell学习笔记及基本命令合集,包含了LINUX常用操作命令和命令行编辑快捷键、shell基本命令,Linux相关使用配置教程等,需要的朋友可下载试试! shell是一个用C语言编写的程序,它是用户使用...
《LINUX与UNIX SHELL编程指南》读书笔记-二次发布版.pdf
Shell作为Unix及类Unix系统(包括Linux)的主要用户界面之一,其历史可以追溯到20世纪70年代。最初,Shell仅仅作为一个简单的命令解释器,随着时间的推移,它发展成为了一个功能强大的编程环境。Shell主要分为两类:...
《LINUX与UNIX SHELL编程指南》是一本深入探讨Linux和UNIX系统中Shell脚本编程技术的书籍。这本书旨在帮助读者理解和掌握Shell编程的核心概念,从而能够编写出高效、实用的自动化脚本,提高日常系统管理和任务执行的...
本平台精心编撰了一份涵盖Linux shell学习要点及基础命令的笔记,旨在为学习者提供一个全面的资源库。该笔记不仅囊括了Linux操作系统中常用的操作命令、命令行编辑的快捷键技巧,还详细介绍了shell的基本命令和相关...
shell编程-shell编程-分支语句(1) shell编程-shell编程-分支语句(2) shell编程-shell编程-循环语句(1) shell编程-shell编程-循环语句(2) Linux的shell编程(一) Linux的shell编程(二) Linux的...
Linux与Unix Shell编程指南读书笔记提供了深入理解和熟练掌握Shell脚本编写技巧的宝贵资源。Shell是Linux和Unix操作系统中的命令解释器,它不仅用于交互式地执行命令,还能编写自动化任务的脚本,极大地提高了系统...
这份学习笔记将深入探讨Shell编程的基础,包括文件权限与安全,这是理解Linux和Unix系统管理的关键。 首先,我们关注文件权限。在Linux和Unix中,每个文件和目录都有三个基本的权限:读(r)、写(w)和执行(x)。...
整理了一份Linux shell学习笔记及基本命令合集,包含了LINUX常用操作命令和命令行编辑快捷键、shell基本命令,Linux相关使用配置教程等,需要的朋友可下载试试! shell是一个用C语言编写的程序,它是用户使用Linux的...
这篇笔记将深入探讨Linux的常用命令,同时也会提及shell编程和makefile的使用,这些都是Linux环境中不可或缺的知识。 1. **Linux常用命令**: - **ls**:列出目录内容,常与`-l`(长格式)和`-a`(显示隐藏文件)...
"Unix Shell编程第三版笔记"是铁道出版社出版的一本教材,它深入浅出地讲解了Unix Shell编程的基础和高级技巧。这份笔记涵盖了从基本的命令行操作到复杂的脚本编写,帮助学习者掌握这一强大的自动化工具。 Unix ...
这部分主要介绍了Linux系统开发中常用的Shell命令,这些命令是进行Linux系统管理、文件操作的基础。 ##### 2.1 目录命令 - **cd**: 改变当前工作目录。 - `cd`: 不带参数则回到用户的家目录。 - `cd /`: 切换到...
### 学习笔记-基础Shell编程 #### 一、Shell编程概述 Shell编程是指利用Shell命令语言编写脚本来实现特定功能的过程。Shell不仅是Linux操作系统下的命令行解释器,还是一种强大的脚本语言,广泛应用于自动化任务...