本文主要来源:
<<Shell 脚本学习指>>
http://blog.csdn.net/lile269/article/details/6387553
http://bbs.chinaunix.net/thread-691881-1-1.html
http://wenku.baidu.com/link?url=PefwLPTAQDnP1HLMpJgJhF04kFLbaBj9GFE9D5MYg0pHX8RsxeheHq_DJuZujDq7rK02GtVbtC-FIfllck8yeqm1GLl1LdkY5N2ILA1TO5i
http://blog.sina.com.cn/s/blog_5e77c61f0100hqky.html
http://blog.csdn.net/weekly123/article/details/1465675
http://blog.163.com/[email protected]/blog/static/16718749120118251544885/
1. Shell正则表达式
(1)meta字符
POSIX BRE与ERE的meta字符
\ : 关闭后续字符的特殊意义。\(...\)与\{.....\}
. : 匹配任何单个的字符,但NULL除外;
* : 匹配它之前的任何数目(或没有)的单个字符
^ : 匹配紧接着的正则表达式,在行或字符串的起始处。
$ : 匹配前面的正则表达式,在字符串或行结尾处。
[...] : 匹配方括号内的任一字符,连字符(-)指的是连续字符的范围; ^符号置于方括号里第一个字符则有反向含义,指的是匹配不在列表内(方括号内)的任何字符。
BRE仅有的
\{n, m\}: 区间表达式(interval expression),匹配在它前面的单个字符重现的次数区间。
\{n\}指的是重现n次;\{n,\}至少重现n次;\{n, m\}指重现n至m次;
\(\): 将\(与\)间的模式存储在特殊的“保留空间(holding space)”。最多可将9个独立的subpattern存储在单个模
式中。可通过转义序列\1到\9,被重复使用在相同模式里。eg:\(ab\).*\1指的是匹配于ab组合的两次重
现,中间可存在任何数目的字符。
\n: 重复在\(与\)方括号内第n个子模式至此点的模式,n为1至9的数字,1为由左开始
ERE独有的:
{n, m}: 与BRE中的\{n, m\}一样
+ : 匹配前面正则表达式的一个或多个实例
? : 匹配前面正则表达式的零个或一个实例
|: 匹配于|符号前或后的正则表达式
( ): 匹配于方括号括起来的正则表达式群
[: :] : 字符集
[. .] :排序符号
[= =]: 等价字符集
(2)后向引用
(3)文本匹配锚点
(4)BRE运算符优先级、由高至低
(5)ERE运算符优先级、由高至低
(6)正则表达式的扩展
2. Shell中重要的命令用法
(1)grep用法
语法: grep [ options ...] pattern-spec [ files...]
用途:打印出与pattern相匹配的行
选项:
常用选项:
-c 只输出匹配行的计数。
-i 不区分大小写(只适用于单字符)。
-h 查询多文件时不显示文件名。
-l 查询多文件时只输出包含匹配字符的文件名。
-n 显示匹配行及行号。
-s 不显示不存在或无匹配文本的错误信息。
-v 显示不包含匹配文本的所有行。
(2)sed用法
工作方式: sed工具按顺序逐行将文件读入到内在中,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内在中,以将其转储至终端,完成操作之后中,读取文件的下一行,重复该过程直到它完成该文件。(输出可被重定向到另一文件中,以保存变化;源文件(默认地)保持不被修改。)
语法: sed [options] '{command}' [filename]
替换命令: 's/{old value}/new value/'
对某一行多次修改: 使用‘-e’选项:
或使用分号:注:分号必须是紧跟/之后的字符,不能出现空格
或使用延续符: >
全局修改: 当某一行中同时出现多个匹配时,仅替换掉第一个,若要替换点全部,需指定全局操作 g
sed可用来修改记录字段分隔符 例:将所有的tab修改为空格: sed 's// /g'
sed修改指定情况下的某些行
用脚本文件来修改,使用 -f 参数:
修改指定的行:
-n 参数:
删除行: 参数:d
sed中的 a 命令: 将文本添加到文件末尾
读写
修改命令:
退出操作: q 命令
&:表示从此点开始替代成匹配于正则表达式的整个文本
实例: sed '2,5d' file 显示文件file,除去2-5行,但行数超过文件实际行数时不会报错。 sed '/10[1-4]/d' file 显示文件file,除去包含101-104的行。
sed '2,$d' file 显示文件,只显示第一行。 sed '2,$!d' file则只显示除第一行外的其它行。
sed '/^ *$/d file 删除文件中的空行。
sed -n '/10[1-4]/p' file 只显示文件file中包含101-104的行。(-n和p必须同时使用,否则只有p时显示全部文件并多显示一次找到的行)
sed -n '5p' file 只显示文件的第5行
sed 's/moding/moden/g' file 将moding替换为moden
sed -n 's/^west/north/p' file 将west开头的行替换为north并显示出来。
sed 's/[0-9][0-9][0-9]$/&.5/' file将file文件中以3个数字结尾的行替换为原数字加".5",&代表搜索到的字符串。
sed 's/\(mod\)ing/\1en/g file 将mod做为模式1封装在括号里,然后替换。
sed 's/...$//' file 删除每一行的最后三个字符。
sed 's/^...//' file 删除每一行的头三个字符。
sed 's#moding#moden#g' file 将moding替换为moden,s后面的#代表搜索串和替换串之间的分界符。
sed -n '/101/,/105/p' file 显示从101的匹配行到105的匹配行。如果只找到101的匹配行,则从101的匹配行到文件末。
sed -n '2,/999/p' file 显示从第2行到匹配行。
sed '/101/,/105/s/$/ 20050119/' file将从101的匹配行到105的匹配行的行末增加" 20050119"内容。
sed -e '1,3d' -e 's/moding/moden/g' file 先删除文件的1-3行,再进行替换。
sed -e '/^#/!d' file 显示文件以#开头的行。
sed '/101/r newfile' file 在每个匹配行增加文件newfile的内容
sed '/101/w newfile' file 把匹配行写入newfile。
sed '/101/a\
> ###' file 在匹配行后增加一新行。
sed '/101/i\
> ###' file 在匹配行前增加一新行。
sed '/101/c\
> ###' file 用新行替换匹配行。
sed 'y/abcd/ABCD/' file 将a、b、c、d分别替换为ABCD。
sed '5q' file 显示到第5行时退出。
sed '/101/{ n; s/moding/moden/g; }' file 在文件中找到匹配行的后一行(n)再进行替换。
sed '/101/{ s/moding/moden/g; q; }' file 在文件中找到第一个匹配行后进行替换后再退出。
sed -e '/101/{ h; d; }' -e '/104/{ G; }' file 在文件中找到与101匹配行后先存在一个缓存中,再放在与104匹配行后。
sed -e '/101/{ h; d; }' -e '/104/{ g; }' file 在文件中找到与101匹配行后先存在一个缓存中,再替代104的匹配行。
sed -e '/101/h' -e '$G' file 将最后一个匹配行放在文件末。
sed -e '/101/h' -e '$g' file 将最后一个匹配行替换文件末行。
sed -e '/101/h' -e '/104/x' file 在文件中找到与101匹配行后先存在一个缓存中,再与104的匹配行进行互换。
sed -f sfile file 根据文件sfile的命令列表进行操作。
cat sfile
/101/a\
####101####\
****101****
/104/c\
####104 deleted####\
****104 deleted****
1i\
####test####\
****test****
(3)cut命令
cut用于从文件或标准输入中读取内容并截取每一行的特定冲毁并送到标准输出。
cut命令主要接受三个定位方法: 字节(bytes),选项为 -b 字符(characters),选项为-c 域(fields),选项为-f
字节定位:
字符定位: (在cygwin下,结果有点问题哦)
-c以字符赤单位 -b以字节为单位
-n选项,告诉cut不要将多字节拆开
“域”操作:对于非固定格式的信息,“域”可派上用场。设置“间隔符”,再设置“提取第几个域”。
在设定-f时,也可以使用例如3-5或者4-类似的格式
(4)join命令
join命令用来连接两个文件中的相同键值的其余内容后输出。 语法: join [options....] file1 file2 选项: -1 field1,-2 field2:选择file1中的field1字段和file2中的field2字段作为键值。 -o file.field:输出file中的field字段。通常file是1或2。 -t seperator:使用seperator作为输入字段的分隔符而非使用空格或TAB. 若想指定file1为标准输入,请使用-
(5)awk命令
可参考资源: http://game-lab.org/wiki/index.php/AWK%E2%80%94%E6%96%87%E6%9C%AC%E6%B5%81%E7%BC%96%E8%BE%91%E5%99%A8
-F 参数的使用:
(6)sort命令
一般格式: sort -cmu -o output_file [other options] +pos1 +pos2 input_files
-c 测试文件是否已经分类。
-m 合并两个分类文件。
-u 删除所有复制行。
-o 存储s o r t结果的输出文件名。
其他选项有:
-b 使用域进行分类时,忽略第一个空格。
-n 指定分类是域上的数字分类。
-t 域分隔符;用非空格或t a b键分隔域。
-r 对分类次序或比较求逆。
+n n为域号。使用此域号开始分类。
n n为域号。在分类比较时忽略此域,一般与+n一起使用。
post1 传递到m,n。m为域号,n为开始分类字符数;例如4,6意即以第5域分类,从第7个字符开始。
-t选项的使用:
缺省情况下,sort认为“一个空格”或“一系列空格”,要加入其他方式分隔,使用-t(-t+分隔符)选项 第一列作为第一个域为域0,域1是第二个域等等。
-c参数的使用:
-r参数:逆向sort结果:
-u参数:唯一性分类
-k参数: 进一步控制排序操作,可使用-k选项指定排序字段,并使用-t选项来选择字段定界符 未指定-t,则表示字段以空白分隔且记录内开头与结尾的空白都将忽略; 指定-t,则被指定的字符会分隔字段,且空白是有意义的。
-k3nr, 3(表示从字段3起始处开始,以数值类型反向排序,并结束于字符3的结尾)或 -k3, 3nr 甚至是-k3,3,-n,-r
文本块排序
(7)uniq命令
uniq有3个选项: 不带参数重复的行仅出现一次 -c在每个输出行前加上该行重复的次数 -d仅显示重复的行 -u仅显示未重复的行
(8)fmt命令
重新格式化文本段落,供用户切分段落 fmt的选项 -s:仅切割较长的行,但不会将短行结合成较长的行 -w n: 则设置输出行宽度为n个字符(默认通常为75个左右)【所有版本都禁止将宽度设置为0,但接受-w 1或-1的用法 】
(9)计算行数、字数及字符数
wc命令:-c(字节数)、 -l(行数)及-w(字数) wf命令:统计每个单词发生频率的相关工具
(10)pr命令
过滤数据为打印作准备
(11)提取开头或结尾数行
3. Shell中的语法
Shell脚本 与函数有位置函数(positional parameter)的功能,即“命令行参数”
(1)变量管理:export与readonly、env
语法: export name[=word] ...
export -p
readonly name[=word] ...
readonly -p
用途: export用于修改或打印环境变量【将变量放进环境里或对共进行修改】,readonly则使得变量不得修改
选项: 使用-p选项,打印出名称及被导出的或只读的所有变量与值; 否则,会将适当的属性应用到指定的变量。
env命令: 可从程序的环境中删除变量,也可改变环境变量值 语法: env [-i] [ var = value...] [command_name [ arguments ... ]] 选项: -i 忽略继承的环境,仅使用命令行上所给定的变量与值
unset命令: 可从执行中的Shell中删除变量与函数 语法: unset [ -v ] variable ... unset -f funciton 选项: -f解除(删除)指定的函数 -v 解除(删除)指定的变量,没有任何选项时,默认的行为是模式【即参数将视为变量名称,并告知变量已删除】
(2)参数展开
参数展开(parameter expansion)是提供变量值在程序中使用的过程
展开运算符
运算符 | 替换 |
---|---|
${varname: - word} | 若varname存在且非null,则返回其值;否则,返回word; 用途:如果变量未定义,则返回默认值 eg:若count未定义,则${count: -0}的值为0 |
${varname:=word} | 若varname存在且不是null,则返回它的值;否则,设置它为word 并返回其值; 用途:若变量未定义,则设置变量为默认值 eg:若count未定义,则${count:=0}设置为0 |
${varname:?message} | 若varname存在且非null,则返回它的值;否则, 显示varname:mesage,并退出当前的命令或脚本 用途:捕捉由于变量未定义所导致的错误 eg:${count:?"undefined!"}将显示count:undefined! 且若count未定义,则退出 |
${varname:+word} | 若varname存在且非null,则返回word;否则,返回null; 用途:为测试变量的存在 eg:若count已定义,则${count:+1}返回1 |
每个运算符内的冒号(:)都是可逆的,若省略冒号,则将每个定义中的“存在且非null”部分改为“存在”,即运算符仅用于测试变量是否存在。
path的值为:/home/tolstoy/mem/long.file.name
运算符 | 替换 |
${variable#pattern} | 若模式匹配于变量值的开头处,则删除匹配的最短部分, 并返回剩下的部分。 eg: ${path#} 结果:long.file.name |
${variable%pattern} | 若模式匹配于变量值的结尾处,则删除匹配的最短部分, 并返回剩下的部分 eg: ${path%.*} 结果:/home/tolstoy/men/long.file |
${variable%%pattern} | 若模式匹配于变量值的结尾处,则删除匹配的最长部分, 并返回剩下的部分。 eg:${path%%.*} 结果:/home/tolstoy/men/long |
位置参数:
位置参数 (positional parameter),指的是Shell脚本 的命令行参数(argument),同时也表示在Shell函数内的函数参数,其名称是以单个的整数来命名。当整数大于9时,就以花括号({})括起来。
符号 | 含义 |
$# | 提供传递到Shell脚本或函数的参数总数 当是为处理选项和参数而建立循环时,会很有用。 |
$*, $@ | 一次表示所有的命令行参数 这两参数可用来把命令行参数 传递给脚本或函数所执行的程序 |
“$*” | 将所有命令行参数视为单个字符串 等同于”$1 $2 ...“ $IFS的第一个字符用来作分隔字符,以分隔不同的值来建立字符串 |
"$@" | 将所有命令行参数视为单个的个体 即单独字符串,等同于"$1" "$2" ...... 是将参数传递给其他程序的最佳方式,因这会保留 所有内嵌在每个参数里的任何空白 |
名称 | 作用 |
set | 调用此命令而未给予任何选项, 它会设置位置参数的值,并将之前 存在的任何值 丢弃 |
shift | 用来”截去(lops off)“来自列表的位置 参数,由左开始。 一旦执行shift,则$1的初始值会永远消失, 取而是$2的旧值,$2的值,变成$3的旧值 还可接受一个可选的参数,即可指定一次要移动几位 默认为1 |
特殊变量
$$变量可在编写脚本时用来建立具有唯一性的文件名(多半是临时的)
算术运算符
与C类似
(3)退出状态
退出的状态值
exit命令
语法 :
exit [ exit- value]
用途:
从Shell脚本 返回一个退出状态给脚本的调用者
行为模式:
若没有提供,则最后一个的执行命令的退出状态作为默认的退出状态。若即为所需,则在Shell脚本里这样写:
exit $?
if-elif-else-fi语句
逻辑的NOT、AND与OR(均属short-cut运算符)
表示逻辑否时的!放在管道(pipeline)前
test命令
test命令可处理Shell脚本里的各类工作,产生的不是一般输出,而是可使用的退出状态。
语法:
test [ expression ]
[ [ expression ] ]
用途:
测试Shell脚本里的条件,通过退出状态返回其结果。特别注意的是:第二种形式中,主括号根据字面意义逐字地输入,且必须与括起来的expression以空白隔开。
行为模式:
test用来测试文件属性、比较字符串及比较数字
(4)case语句
(5)循环
for循环
while与until循环
break与continue
通过结合while、case、break及shift,可做些简单的选项处理
getopts命令用法
语法:
getopts option_spec variable [ arguments ... ]
用途
简化参数处理,并让Shell脚本可轻松地匹配于POSIX参数处理惯例
行为模式
(6)函数
(7)输入/输出、文件与命令执行
Standard I/O
Standard input、Standard output、Standard error
使用read读取行
read命令用法
语法:read [ -r ] variable ...
用途:将信息读入一个或多个Shell变量
主要选项:-r 【原始读取,不作任何处理,不将行结尾处的反斜杠解释为续行字符】
关于重定向
基本的输入输出重定向运算符: <、 >、 >>及|
额外的重定向运算符:
使用set -C搭配,防止文件意外截断的选项;执行set -C命令可打开Shell所谓的禁止覆盖(nocolbber)选项,当它处于打开状态时,单纯的>重定向遇到目标文件已存在时,会失败;>|运算符则可令noclobber选项失效。
提供行输入(inline input)的<<与<<-:
使用program << delimiter,可在Shell脚本正文内提供输入数据,这样的数据叫作嵌入文件(here document)。
printf命令:
语法: printf format-string [arguments ... ]
(8)波浪号展开与通配符
文件名操作:~将用户根目录的符号型表示方式,改为实际的目录路径,可采用直接或间接的方式指定此程序的用户。
*表示所有的文件名
(9)引用
引用(quoting)是用来防止Shell将某些你想要的东西解释成不同的意义。 三种引用的方式: 反斜杠转义(\),用来告知Shell该字符即为字面上的意义。 单引号('...')强制Shell将一对引号之间的所有字符都看作其字面上的意义。Shell脚本会删除这两个引号,只单独留下被括起来的完整文字内容。 双引号(“...”)跟单引号类似,将括起来的文字视为单一字符串,不过,双引号会确切地处理括起来文字中的转义字符和变量、算术、命令替换。
(10)subShell与代码块
subShell:
是一群被括在圆括号里的命令,这些命令会在另外的进程中执行。
当需让一小组的命令在不同的目录下执行时,可用该方法,不必修改主脚本的目录,直接处理这种情况。
4. awk
命令行: awk [- F fs] [-v var=value ... ] 'program' [ -- ] \ [ var=value ... ] [ file(s) ](短程序在直接在命令行上提供) awk [ -F fs] [ -v var=value ...] -f programfile [ -- ] \ [ var=value ... ] [ file(s) ](较长的程序由委托-f选项指定)
--选项:特殊选项,指出awk本身已没有更进一步的命令行选项,任何接下来的选项赌阿被程序使用。 -F选项:用来重新定义默认字段分隔字符,一般作为第一个命令行选项。 fs参数:是一个正则表达式,或是被提供作为下一个参数。 -v选项:须放在命令行上直接给定的任何程序之前,它们会在程序启动之前以及处理任何文件之前生效、在命令行程序之后的-v选项会被解释为一个文件名。
(1)awk程序模型
awk程序是一对以模式(pattern)与大括号框起来的操作(action)组合而成的,还会加上实现操作细节的函数(function)。针对每个匹配于输入数据的模式,操作会被执行,且所有模式都会针对每条输入记录而检查。
(2)标量变量与数组变量
保存单一值的变量叫做标量变量
数组变量:包含零到多个数据项,通过紧接着名称的数组索引选定。awk允许在数组名称之后,以方括号将任意数字或字符串表达式括起来作为索引。
(3)记录与字段
在awk程序化模式中,通过输入文件隐含循环的每一次迭代,会处理单一记录(record),通常是一行文本。记录可进一步再分割为更小的字符串,叫做字段(field)。
记录分隔字符(RS):gawk中RS可以是正则表达式,可提供比单一字符还长的长度。
eg:RS = "+"匹配于字面上的一个加号,而RS = ":+"匹配于一个或多个冒号,提供了更强大的规格。
字段分隔字符(FS):字段彼此是被匹配字段分隔字符正则表达式(可在变量FS里取得)的当前字符串值分隔。
字段可以特殊名称$1、$2、$3、....、$NF供awk程序使用,字段引用无须是固定的,可转换(通过截断)为整数值。
特殊字段名称$0引用当前记录,初始值是从输入流中读取,且记录分隔字符不是记录的一部分。引用到0到NF范围以上的字段编号是不会有错的,它们会返回空字符串,且不会建立新字段,除非指定值给它们。
(4)模式与操作
模式:由字符串/或数值表达式构建而成,当计算出当前输入记录的值为非零(真),则实行结合性的操作
(5)语句
连续执行:
条件式执行:
重复执行:
用户控制的输入getline
(6)字符串函数
length(string):用来返回字符串string的长度
子字符串提取:
substr(string, start, len):提取子字符串的函数;
字母大小写转换:
tolower(string):将所有字母改为小写;
toupper(string):将所有字母改为大写;
字符串查找:
index(string,find):查找string里是否有字符串find,返回string里的find字符串的起始位置;若string里找不到find,则返回0;
字符串匹配:
match(string,regexp):将string与正则表达式regexp匹配,若匹配,则返回匹配string的索引,不匹配,则返回0。
字符串替换:
sub(regexp,replacement,target):将target与正则表达式regexp进行匹配,将最左边最长的匹配部分替换为字符串replacement;返替换的数目,若活力第三个参数,则默认值为当前记录$0.
gsub(regexp,replacement,target):与sub有些类似,不过它会替换所有匹配的字符串。
注意:这两个函数的调用过程中,每个replacement里的字符&都会被替换为target中与regexp匹配的文本,使用\&可关闭这一功能,且请刻若要在引号字符串里使用它时,以双反斜杠转义它。
字符串分割
split(string, array, regexp):将string切割为片段,并存储到array里的连续元素。
字符串重建
join():
字符串格式化
sprintf(format, expressoin1, expression2, ... ):会返回已格式化的字符串作为其函数值