shell 学习笔记

$PATH 里的主项目(empty componen t ) 表示当前目录(currenl directory) . 空项目位于路径世中间时,可以用两个连续的冒号来褒表示.如果将冒号直接置于最前端或者尾端,
可以分别表示查找时最先查找或者最后查找当前目录
PATH=:/bin:/usr/bin:/usr/XllR6/bin:/usr/local/bin 先找当前目录
PATH=/bin:/usr/bin:/usr/XllR6/bin:/usrtlocaltbin 最后找当前目录
PATH=/bin:/usr/bin:/usrl/lR/tbin: : /usr/local/bin 当前目录层中
如果你希望将当前目录纳入查找路径(search path). 更好的做法是在$PATH 中使用点号(dot ) ; 这可以让阅读程序的人更清楚程序在做什么。

访问 Shell 脚本的参数

所谓的位置参数 (positional parame t ers) 指的也就是 Shell 脚本的命令行参数 (command lÎne arguments)~ 在 shell函数里里, 他们也可以同时是函数的参数,各个参数由整数来命名.由于历虫的原因,当 超过 9 , 就应该用大括号把数字框起来

echo first arg is $1
echo tenth arg is ${10}

简单的执行跟踪


程序是人写的,难免会出错。想知道你的程序正在做什么,有个好方法,就是把执行跟踪 (execution tracing) 的功能打开。这会使得 Shell 显示每个被执行到的命令,并在前
面加上"+":一个加号后面眼着一个空格。(你可以通过给 Shell 变量 PS4 赋一个新值以改变打印方式。)

你可以在脚本里,用 set -x 命令将执行跟踪的功能打开,然后再用 set +x 命令关闭它。这个功能对复杂的脚本比较有用,不过这里只用简单的程序来做说明:

#! /bin/sh
set -x
echo 1st echo

set +x
echo 2nd echo
study_shell$ ./trace1.sh 
+ echo 1st echo
1st echo
+ set +x
2nd echo

正则匹配

方括号表达式 (bracket expression).匹配方括号内的任一字符。连字符(- )指的是连续字符的范围(注意范围会因 locale 而有所不同,因此不具可移植性). ^符号置于方括号里第一个字符则有反向含义 ,指的是匹配不在列表内(方括号内)的任何字符。作为首字符的一个连字符或是结束方括号(]) ,则被视为列表的一部分。所有其他的 meta 字符也为列表的一部分(也就是 2 根据其字面上的意义)。方括号表达式里可能会含有排序符号( collatingsymbol) 、等价字符集 (equivalenceclass)(文后将有介绍)。

在方括号表达式中,所有其他的 meta 字符都会失去其特殊含义。所以[*\. ]匹配于字面上的星号、反斜杠以及句点。要让]进入该集合,可以将它放在列表的最前面: []*\.] ,将]增加至此列表中。要让减号字符进入该集合,也请将它放到列表最前端: [-*\. ]。若你需要右方括号与减号两者进入列表,请将右方括号放到第一个字符、减号放到最后一个字符: []*\.-]。 

后向引用

BRE 提供一种叫后向引用(backreferences) 的机制,指的是"匹配于正则表达式匹配的先前的部分"。使用后向引用的步骤有两个。第一步是将子表达式包围在\(与\)里 ;单个模式里可包括至多 9 个子表达式,且可为嵌套结构。下一步是在同一模式之后使用\ digit , digit 指的是介于 1 至 9 的数字,指的是"匹配于第 n 个先前方括号内子表达式匹配成功的字符"。举例如下:
模式                                                           匹配成功
\(ab\)\(cd\) [def]*\2\ 1                         abcdcdab、 abcdeeecdab、 abcdddeeffcdab
\(why\) . *\1                                        一行里重现两个 why
\([ [:alpha: _][[ :alnum: _] *\) = \1;      简易 CIC++ 赋值语句
后向引用在寻找重复字以及匹配引号时特别好用:
\( [ "']\). *\1               匹配以单引号或双引号括起来的字,例如 'foo' 或'bar"
在这种方法下,就无须担心是单引号或是双引号先找到。

 文本块排序-sort 运用


有时,你会需要将多行记录组合而成的数据排序。地址清单就是一个很好的例子,为了方便阅读,地址记录经常会切断,以一个或数个空行将彼此隔开。像这种数据,没有一定的排序键值位置可供一 k 选项使用,所以你得自救,提供一些额外标记 (markup) 给这些数据。这里是一个简单范例:

# SORTKEY:Schloß ,hans Jürgen
Hans Jürgen Schloß
Unter den Linden 78
D-10117 Berlin
Germany

# SORTKEY: Jones , Adrian
Adrian Jones
371 Montgomery park Road
Henley-on-Thames RG9 4AJ
UK

# SORTKEY: Brow口, Kim
Kim Brown
1841 S Main Street
Westchester , NY 10502
USA

这里的排序小技巧,就是利用 awk 处理较一般性的记录分隔字符的能力,识别段落间隔,在每个地址内暂时使用一个未使用过的字符(例如使用一个无也打印的控制字符) ,取代分行,以及用换行字符取代段落间隔。 sort 看到的行就会变成这样:

# SORTKEY: Schloß , Hans Jürgen^ZHans Jürgen Schloß^ZUnter den Linden 78^Z...
# SORTKEY: Jones , Adrian^ZAdrian Jo口 es^Z371 Montgomery park Road^Z...
# SORTKEY: Brow口, Kim^ZKim Brown^Z1841 S Main Street^Z...

在这里,^Z是一个 Ctrl-Z 字符。第一个过谑步骤是通过 sort 排序后恢复换行与段落的分隔符号,且排序键值行是容易删除的,如有需要,可使用 grep 轻松地删除它们。整个管道看起来就像这样:

cat my-friends | 
awk -v RS="" '{gsub("\n","^Z");print }' | 
sort -f | 
awk -v ORS="\n\n" '{ gsub("\^Z","\n");print }' | 
grep -v '#SORTKEY'

函数 gsub( )功能为全局性替换 (global substitution) ,类似 sed 下的 s/x/y/g 架构。RS 变量是输入数据的记录分隔器 (Record Separator) 。通常输入数据是以换行字符隔开,使每一行成为单个的记录。 “RS=""”是一个特殊用法,指的是记录以空行的方式隔开 ; 例如每个块或文本段落自成一个记录。这就是我们的例子里输入的数据形式。最后, ORS 指的是输出记录分隔器 (Output Record Separator) I 以 print 显示的每条输出记录会以其值作为终止。一般来说默认值为单个换行字符$在此设置它为 "\n\n" ,是为了保持用空白行分隔记录的输入格式

 time

time命令 用于 打印出一条命令或一个程序的执行时间
time 命令以秒为单位将一条命令执行期间所用的时间、系统时间和 time 命令的执行时间打印在标准错误中。

用法:time [ -p ] Command [ Argument ... ]
举例:想知道 列举home文件夹这一命令 花费的时间:
      time ls /home
      想知道 将文件复制到某一文件夹 花费的时间:
      time cp /home/***/h /home/***/Documents 
      想知道 一个脚本运行的时间:
      time ./helloWorld.sh

time命令结果有三行组成:real、user和sys。我们这里用的都是real值,CPU用时被划分为user和sys两块。

real值表示从程序开始到程序执行结束时所消耗的时间,包括CPU的用时

user值表示程序本身,以及它所调用的库中的子例程使用的时间

sys是由程序直接或间接调用的系统调用执行的时间

在单处理器上,real值和整个CPU用时之差,也就是real - ( user + sys )是所有延迟程序执行的因素的总和。在SMP上,这个值近似为real * number_of_processors - ( user + sys )。这些因素包括:
•调入程序文本和数据的IO操作 
•获取程序实际使用内存的IO操作 
•由其它程序消耗的CPU用时 
•由操作系统消耗的CPU用时

fmt

fmt指令会从指定的文件里读取内容,将其依照指定格式重新编排後,输出到标准输出设备。若指定的文件名为"-",则fmt指令会从标准输入设备读取数据。

虽然 一 些 fmt 的实现有较多的选项可用,但其实我们发现只有两种较 常 用到:- s 仅 切割较长的行,但不会将短行结合成较长的行,而 -w n 则设置输出行宽度为 n 个字符(默
认通常的 75 个左右) .

qiweijie@qiweijie:~/study_shell$ sed -n -e 9991,10010p /usr/share/dict/words | fmt
Merak's Mercado Mercado's Mercator Mercedes Mercer Mercer's Mercia Merck
Merck's Mercuries Mercurochrome Mercurochrome's Mercury Mercury's Meredith
Merino Merle Merle's Merlin
qiweijie@qiweijie:~/study_shell$ sed -n -e 9991,10010p /usr/share/dict/words | fmt -w 30
Merak's Mercado Mercado's
Mercator Mercedes Mercer
Mercer's Mercia Merck Merck's
Mercuries Mercurochrome
Mercurochrome's Mercury
Mercury's Meredith Merino
Merle Merle's Merlin
qiweijie@qiweijie:~/study_shell$ 

tr 

tr [OPTION]... SET1 [SET2]  

[功能] 

转换或者删除字符。 

[描述] 

tr指令从标准输入设备读取数据,经过字符串转译后,输出到标准输出设备。 

通过使用 tr,您可以非常容易地实现 sed 的许多最基本功能。您可以将 tr 看作为 sed 的(极其)简化的变体:它可以用一个字符来替换另一个字符,或者可以完全除去一些字符。您也可以用它来除去重复字符。这就是所有 tr 所能够做的。 

tr用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。 

参数: 

  -c或--complerment   取代所有不属于第一字符集的字符。 

  -d或--delete   删除所有属于第一字符集的字符。 

  -s或--squeeze-repeats   把连续重复的字符以单独一个字符表示。 

  -t或--truncate-set1   这个比较难理解,man上面的解释是:first truncate SET1 to length of SET2,经过我的实践发现,将set1的字符依次替换成set2中的字符,如果set1中的字符数目超过set2,那么set1多出的字符忽略。如果没有-t,那么多出的字符都替换成set2的最后一个字符。 

  --help   在线帮助。 

  --version   显示版本信息。 

export

export 用于修改或打印坏境宜量, readonly 则使得变量不得修改­

 

expart 命令可以将新变量添加到环境中:
PATH=$PATH:/usr/local/bin   更新 PATH
export PATH                         导出它

set,env和export这三个命令的区别

set命令显示当前shell的变量,包括当前用户的变量;

env命令显示当前用户的变量;

export命令显示当前导出成用户变量的shell变量

 

p

posted @ 2015-11-23 14:42  2BiTT  阅读(413)  评论(0编辑  收藏  举报