Shell编程笔记
1.基础概述
Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合。
Shell可以直接使用在win/Unix/Linux上面,并且可以调用大量系统内部的功能来解释执行程序,如果熟练掌握Shell脚本,可以让我们操作计算机变得更加轻松,也会节省很多时间。
Shell不是具体哪一款程序,是一类程序的统称,这些程序只要是能够按照用户的要求去调用操作系统的接口,就可以称之为Shell程序.
linux发展至今,有许多shell程序,其中一款软件叫做bash。
1.1 基础命令
1.1.2 找出登录人员:who命令
who
1.1.3 回显字符:echo命令
echo命令会在终端打印出(或者说回显)你在行中输入的所有内容,且echo会将单词间多余的空白字符压缩,通常会忽略多余的空白字符。
echo this is test
echo ?
echo a?
echo ??
echo ??*
echo *
1.2 使用文件
UNIX系统只识别三种基本类型的文件:普通文件、目录文件和特殊文件。
1.2.3 统计文件中单词数量:wc命令
wc命令可以获得文件中的行数、单词数和字符数。需要将待统计的文件名作为该命令的参数。
wc [参数] [文件名]
l 统计文件包含的行数
c 统计文件中包含的字符数
w 统计文件中包含的单词数
1.3.1 主目录和路径名
按照惯例,【…】指向当前目录的上一级目录,也称为父目录。
另一种惯用写法是单点号【.】,他总是引用当前目录。
1.4.1 星号
Shell有一个强大的特性:文件名的替换。Shell会自动将模式【*】替换成当前目录下能够匹配到的所有文件名。
1.4.2 匹配单个字符
星号(*)能够匹配零个或多个字符,也就是说,x星能够匹配文件x,也能够匹配x1、x2、xabc等。问号(?)仅能匹配单个字符。
破折号(-)指定一个字符的逻辑范围。例如,[0-9]能够匹配字符0~9。在指定字符范围的时候,唯一的限制就是第一个字符在字母表上的必须位于最后一个字符之前。
1.5.1 文件名中的空格
有两种解决办法:使用反斜杠将所有空格进行转义,或者将整个文件名放在引号中,让Shell指导这是一个包含了空格的单词,并非多个单词。
例:
cat "my test document"
cat "my\test\document"
1.6 标准输入/输出和I/O重定向
1.6.1 标准输入和标准输出
UNIX命令可以使用文件或上一条命令的输出作为其输入,也可以将其输出发送给另一条命令或其它程序。这个概念极其重要。
Ctrl+d,表示数据输入完毕。
1.6.2 输出重定向
将发送到标准输出的命令输出转移到文件中,即叫做输出重定向。
如果将【>file】放置在能够将输出写入到标准输出上的命令之后,那么该命令的输出就会被写入到文件【file】中:
who > users
注意:这个不会有任何输出内容出现,因为输出已经从默认的标准输出设备(终端)重定向到了指定文件中。
如果命令的输出被重定向到某个文件,而这个文件中之前已经有了内容存在,那么这个已有的内容会被重写。
当使用字符【>>】时表示另一种类型的输出重定向。这组字符使得命令的标准输出内容被追加到指定文件的现有内容之后,文件中先前的内容并不会丢失,新的输出只不过被添加到尾部而已。
例:
cat file1 >> file2
1.6.3 输入重定向
正如命令的输出可以被重定向到文件中,文件也可以被重定向命令的输入中。小于号【<】则被作为输入重定向符号。只有哪些从标准输入中接收输入的指令擦能够使用这种方法将文件重定向到其输入中。
1.7 管道
1.7.1 管道
UNIX能够将两个命令“连接”在一起,这种连接叫做管道,它可以将一个命令的输出直接作为另一个命令的输入。
管道使用字符【|】表示,被放置在两个命令之间。例如,在【who】和【wc -l】之间创建一个管道,可以输入:
who | wc -l
管道可以在任意两个程序间创建,前提是第一个程序会将输出写入到标准输出,第二个程序会从标准输入中读取输入。
1.7.1 过滤器
可以从标准输入中接收输入,对输入数据进行处理,然后将结果写入标准输出。总的来说就是用来在管道中修改其他程序输出的程序。
cat、sort都可以作为过滤器。
ls、who、date、cd、pwd、echo、rm、mv、及cp并没有从标准输入中读取输入,不是过滤器。
1.9.1 在一行中输入多个命令
如果在一行中输入多个命令,只需要使用分号作为命令之间的分隔符就行。
1.9.3 ps命令
ps命令能够给出系统中所运行的进程信息。
如果配合【-f】选项,ps会打印出更多的进程信息,包括父进程ID(PPID)、进程开始时间(STIME)及其他命令参数。
2.什么是Shell
2.1 内核和实用工具
UNIX系统在逻辑上被划分为两个不同的部分:内核和实用工具(Utility),通常来说,所有访问都要经由Shell,Shell是一个实用工具程序,它作为登录过程的一部分被载入到内存中执行。
2.3 在Shell中输入命令
重要的要认识到Shell是一个程序,在系统中没有什么特权。
2.4 Shell的职责
(1)程序执行
(2)变量及文件明替换
(3)I/O重定向
(4)管道
(5)环境控制
(6)解释型编程语言
3.常备工具
3.1 正则表达式
正则表达式给出了一种便捷、一致的方式来指定待匹配的模式。
Shell认为【?】能够匹配任意单个字符,而在正则表达式中(regular expression,通常简写为regex)则是使用点号(.)来实现相同的效果。
3.1.1 匹配任意字符:点号(.)
正则表达式
r.
正则表达式
.x.
正则表达式:查找功能
/ ... /
注:编辑器ed是一个旧式的行编辑器,一直存在与Linux中
ed命令正则表达式测试:
ed temp.txt #使用ed编辑器打开文件,然后终端后会打印出文件中总的字符数
1,$p #打印出全部行,【p】为打印命令,【$】为范围限定符,
#最基本的范围限定符就是1,$,这表示从文件的第一行到最后一行
/ ... / #表示查找由空格包围的3个字符
/ #表示重复最后一次查询(继续搜索)
1,$s/p.o/XXX/g #将所有的p.o修改成XXX,【s】为替换命令,【g】表示执行全局替换
3.1.2 匹配行首:脱字符(^)
脱字符^作为正则表达式的第一个字符,用来匹配行首位置
/the/
/^the/
1,$s/^/>>/
1,$s/^/ /
3.1.3 匹配行尾:美元符号($)
点号可以匹配任意字符,因此正则表达式【$】匹配的是行尾的任意字符(包括点号)。
如何匹配点号?一般而言,如果你想匹配任何对于正则表达式来说有特殊含义的字符,可以在该字符前加一个反斜杠(\)来去除其特殊含义。
\.$
^\.
/\.$/
1,$s/..$//
^$
^ $
3.1.4 匹配字符组:【…】
[tT]he
/[tT]he/
1,$s/aeiouAEIOU//g
[123456789] 或 [0-9]
[A-Z]
[A-Za-z]
/^[A-Z]/
在ed编辑器中,像*、.、[…]、$和^这类正则表达式序列仅在搜索字符串中有意义,在替换字符串中没有任何特殊含义。
如果脱字符(^)是左中括号后的第一个字符,那么所匹配内容的意义就相反了(相比之下,Shell使用!来实现相同的效果)
[^A-Z]
[^A-Za-z]
3.1.5 匹配零个或多个字符:星号(*)
+可用于匹配一次或多次出现在其之前的表达式,因此以下两种表达方式在功能上没有什么不同
XX*
XXX*
X+
1,$s/ */ /
.*
正则表达式
1,$s/e.*e/+++/
[A-Za-z][A-Za-z]*
[]a-z]
3.1.6 匹配固定次数的子模式:\{…\}
通用来精确指定需要匹配的字符数量:
\{min,max\}
X\{1,10\}
几种特殊情况:
\{10\}
.\{10\}
1,$s/^.\{10\}//
1,$s/.\{5\}$//
+\{5,\}
3.1.7 保存已匹配的字符:\(…\)
要想引用已经由正则表达式匹配到的字符,可以将这部分正则表达式放在由反斜线转义过得括号里。这些被捕获到的字符会被保存在由正则表达式解析器预定义好的叫做寄存器的变量中,其编号从1到9。
^\(.\)
^\(.\)\1
^\(.\).*\1$
连续出现的\(…\)可以将其匹配的内容分配给后续的多个寄存器。例:
^\(...\)\(...\)
^\(...\)\(...\)\2\1
在ed中使用替换命令时,寄存器也可以作为替换字符串中的一部分引用。
1,$s/\(.*\) \(.*\)/\2 \1/
3.2 cut
该命令在从数据文件或命令输出中提取(切出)各种字段的时候非常方便。
cut -cchars file
其中,“chars”指定了你想从file中的每行内提取哪些字符(依据位置)包含: (1)单个数字;如-c5,可以从输入的每行中提取第5个字符
(2)以逗号分隔的数字列表;如,-c1,13,50,可以提取第1个、第13个、第50个字符
(3)连接符分隔的数字范围;如-c20-50,可以提取第20~50个字符
cut -c5- data
如果没有指定file,cut会从标准输入中读取输入,这意味着你可以在管道中将cut作为过滤器使用。
可以利用cut从文本行中提取不同位置上的字符,如下:
who | cut -c1-8,18-
cut [参数] [文件名]
-d 指定字段分隔符
-f 指定待提取的字段
cut -d: -f1,6 /etc/passwd
如果在不使用-d选项的情况下用cut命令从文件中提取字段,则使用制表符作为默认的字段分隔符,而不是空格。
如果字段是由制表符分隔的,可以使用cut的-f选项:
cut -f1 phonebook
拓展:制表符
制表符即相当于键盘上的 Tab键(Q的左方,Caps lock的上方) 在格式控制输出中用“\t”表示 相当于回车在printf中用“\n”表示
通常用于将输出对齐
如何知道字段是有空格还是由制表符分隔的?
(1)试错法
(2)命令:
sed -n 1 file
如果字段是由制表符分隔的,在制表符的位置上显示:\t
3.3 paste
paste 命令的效果和cut相反;它不是拆分行,而是合并行。该命令的一般格式为:
paste files
由files指定的每个文件中对应的行被“粘贴”或合并在一起,形成一行,然后写入到标准文件中(两者之间由制表符分隔)。连接符“-”可以用在files中,将输入源指定为标准输入。
paste [参数] [列前文件名] [列后文件名]
-d 指定单个分隔符,该分隔符用来分隔粘贴的所有字段
-s 指定paste只能从同一个文件中粘贴行,不管其他文件,如果指定了单个文件,其效果是将该文件中所有的行合并到一 起,彼此之间用制表符分隔(或者是由-d选项指定的分隔符)
例:
paste -d'+' names address numbers
paste -s names
ls | paste -d' ' -s -
|