Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103035
  • 博文数量: 42
  • 博客积分: 1445
  • 博客等级: 上尉
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-28 13:57
文章分类

全部博文(42)

文章存档

2010年(10)

2009年(32)

我的朋友

分类:

2009-10-16 09:56:12

shell 识别三种命令: 内建命令 shell函数 外部命令

外部命令是由shell 新的进程所执行的命令
a 建立一个新的进程
b 在path 里查找
c找到新进程取代执行中的shell

在shell的变量值可以是null
ex:fullname = “a b c”  包含空格时 需用引号  
    fullname = “$a $b $c” 多个变量连接也要引号

print 会自动包含\n  printf 则需要执行添加

关于path
path=:/bin:/usr/bin 先查找当前
path=/bin:/usr/bin:  最后查找当前
path=/bin::/usr/bin  中间查找当前  (注意的是:冒号)

locale -a 列出所有系统说支持的locale
locale -ck 查询特定的locale变量
ex:locale -ck LC_TIME

在正则下
\ 关闭后续字符的特殊定义,但\(\) \{\}会打开其特殊定义
. 任何单个字符
* 0个或多个 在它之前的单个字符
  单独出现时 在BRE中不具有任何意义(因为前面为空 就什么都没有)
^ 在BRE中  在表达式开头处具有意义
  在ERE中  任何位置都有意义
$ 同上,只是他代表的是结尾处
[] 匹配方括号内任一字符
   - 在这里的意思是连续 ex:1-9  1到9
   ^ 代表非
在方括号表达式中,所有的meta字符都会失去特殊含义
[]*\.-]这个例子比较特殊 对] 跟-  放进[]里的位置有些许讲究
\(['"]\).*\1 这个的意思是 ''或者“”,
不用担心单引号先找到或者是双引号先找到

   
注:BRE 基础正则表达式 ERE 扩展正则表达式
注:
[::] 字符集 ex: [:alpha:] 字母字符 [:alnum:] 数字字符
    [:upper:] 大写 [:lower:] 小写 [:space:] 空格
[..] 多字符序列视为一个单位
[==]等价字符集 对于有音标的才需要

后向引用
\( \)  配一个\n
ex:\( \)\1 表示引用前面的一次,那就是() ()  原来有一次,再应用一次
另外注意的是,n代表1-9  最多可以9次的应用,顺序是从左开始

-------
((read|write)[[:space:]]*)+
解释 :  ( )+ 一次或多次括号里面的
    ( ) [[:space:]]*  ()后接一个或多个空格
    read|write  在ERE里面这个表示交替 不是read就是write

------
\< 匹配单词头
\> 匹配档次尾
\< \> 只匹配单词

-----------
head -n
awk 'FNR <= n '  (FNR是在当前输入文件的记录数)
sed -e nq
作用都是类似的 打印前N行



sed定界符可以变,不一定是/
sed 's:/a:/b:'

sed 's/a/&,abcd' &代表了前面的表达式
sed 's/ /av' 空格代表 使用上一次所使用的表达式

sed 的完整表达式是address +commend
所以sed 可以
sed '/a/s/#/$/' 指定一个地址,行
表示从含有a那行开始,再匹配#,然后将其转换为$
sed '/a/,/b/s/#/$/'
从含有a那行开始,到含有b的那行结束,所有行第一个#取代为$


-------

 ${varname:-word}
如果varname存在且不是null,则返回他的值,否则返回默认值
${count:-0} 如果count没定义,则值为0

${varname:=word}
如果varname存在且不是null,则返回他的值,则设置变量为默认值
${count:=0} 如果count未定义,则count设置为0

${varname:?message}
如果varname存在且不是null,则返回他的值,否则,显示message并退出当前命令
${count:?"undefined!"}  如果count未定义,就显示count:undefined并退出

${varname:+word}
如果varname存在且不是null,则返回word,否则返回null
${count:+1} 如果count已定义,则返回1

------

#     从前面开始匹配的,并删除匹配最短
##     从前面开始匹配的,并删除匹配最长
$    从后面开始匹配,并删除匹配最短
$$    从后面开始匹配,并删除匹配最长

------

$#    进程参数个数
$@    当前命令行的参数,置于双引号内,展开为个别参数
$*    当前命令行的参数,置于双引号内,展开为单独参数
个别参数即单个字符串 "$1 $2" 单独参数即单独字符串 "$1" "$2"
$?    前一命令的退出状态
$$    当前进程pid
$0    程序的名称
$!    最近一个后台命令的进程编号
IFS    shell默认的分割字段的,默认值是空格 tab 换行
PPID    父进程编号
ps4   

------
test   -u  suid
    -g sgid
    -z  string为null
    -n string是非null
    = sting1与string2相同
    -eq  整数相等

------

[-abc-]        匹配字符-abc之一
[^ab^c] 匹配不是a或b或^或c的任意字符
字符]和[放在[]中,只有紧跟在[后面的]和紧贴于]前面的[是普通字符

^ - [ ]这几个字符在[]中的意义和其位置有关,原理就不多说了,就写这几个例子。

^\(.\)   行中第一个字符存到1号寄存器中
^\(.\)\1 行首两个字符,且他们相同
^\(.\).*\1$ 行首尾两个字符相同

[0-1][0-9][-/][0-3][0-9][-/][0-9]\{2\}
这个表达式能够用来表示时间格式MM-DD-YY或MM/DD/YY,方括号[]中的-放在第一个位置,确保它在[]中不被解释为范围,而是普通字符-

^.*$和.*都匹配任意行(包括空行)

shell的*相当于re的.*
shell的?相当于re的.
shell的*和?也不是任何地方有意义的,一般用于路径中扩展文件名(至于有没有其他地方用还不知道)

sed 命令的基本格式(单引号里面的格式)
sed '地址 动作'   地址和动作之间不需要空格(这里方便看)

地址有2种形式:
1、行号,以数字表示;特殊的,行号中的$表示尾行(其他地方表示行尾)
2、模式,以//包围正则构成。
地址最多可以指定2个,且指定2个时需要用逗号,隔开表示范围;行号和模式可以混用。如:
sed '/a/,$s/#/$/' file
sed '1,/a/s/#/$/' file

当某个地址后有超过一个动作,需要使用{}和;
sed '/a/,${s/#/$/;s/#/$/2}' file       2表示替换第二个(最好实验一下,你会有新发现)

-----
test 的内容再整合一下
test -u  suid
    -g sgid
    -z  string为null
    -n string是非null
    = sting1与string2相同  !=不等
    -eq  整数相等 -ne不等  -gt大于  -ge大于等于  -lt小于  -le小于等于    都是整数比较
      -e file  存在
      -d file  目录
      -f file  普通文件
      -r file  可读
      -w file  可写
      -x file  可执行
      -s file  长度不为0
      -L file  符号链接
      -a 并且
      -o 或者
      ! 非
-----
单引号' '屏蔽所有字符的特殊意义(包括回车)
双引号" "屏蔽大多数字符的特殊意义,除了美元$ 反斜杠\ 反引号`
反斜杠' '屏蔽所有单个字符的特殊意义,相当于  '单个字符'(但是有一些小意外)
以上普通的例子就不举了,说一下上面提到的“意外”:

当反斜杠用于一行的最后一个字符时,shell把行尾的反斜杠作为续行,它去掉跟在后面的换行字符,
也不把换行符当作参数分隔符(就像该字符从来没有键入过一样)。这种结构在分几行键入命令时经常使用。

\n \r \b \t 等等有自身的特殊意义,不在反斜杠屏蔽的范围里面,但是放在单引号内的话照样全部屏蔽。

另外再提一下,单、双引号都能屏蔽换行、空格和Tab的参数分隔(IFS)意义,利用这一点可以在脚本中用引号
输入大段文字而不用担心换行的问题,管道符|也有这个作用。

-----
再说一下if [ ]
if这个东西几乎在所有变成语言里都有,大多数语言中if的格式都是if (condition)....有的后面有then,有的没有。
其他语言中的if( )和shell中的if [ ]很像,只是括号的样子不一样而已。然而他们是有本质区别的!
if ( )中的( )是个固定格式(大部分语言中是这样),不能变的;而if [ ]中的[ ]是shell的内部命令,并不是固定的
格式。shell中的if的标准格式是
if command
then
   commands
fi

if根据它后面command的返回状态来判断执行then后面的commands还是不执行:返回0就执行,非0就不执行。
[ ]是shell内置的判断命令,和命令test等效。所以当你看到if后面不是[ ]时,请不要惊讶。

-----
sed的N命令:追加下一行
多行Next(N)命令通过读取当前行的下一行,并把两行拼成一行来进行接下来的处理。
$ cat file
line 1
line 2
line 3
line 4
file文件中的每一行后面都有一个隐藏的换行符”\n”,sed不对每行末尾的”\n”进行处理。
$ sed N file
line 1
line 2
line 3
line 4
经过N处理过的输出和原文件没有区别,但是本质是不一样的。这里sed其实认为自己打印的是2行,第一行为”line 1\nline 2”,而第2行为”line 3\nline 4”,注意这里的2行末尾依然隐藏换行符”\n”,sed依然不处理行尾的”\n”,但是处理行内的”\n”。因为这里默认的动作是打印,所以处理行内的”\n”我们也看不出来。
值得注意的是,处理line 1时,line 2被读入并追加到line 1后面,所以line 1处理完后不再读入line 2(前面已经读过了)而直接读入line 3进行下一个N命令(即读入line 4并追加到line 3后面)。
上面2段如果不理解的话,看下面这个命令:
$ sed ‘N;s/\n/ /g’ file
line 1 line 2
line 3 lin3 4
这个命令在原来的基础上把行内的”\n”替换成空格了(尽管用了全局替换标志g,sed依然不处理行尾换行符!),看明白N的作用了吗,单独的N可以创建2行模式空间。 
阅读(792) | 评论(0) | 转发(0) |
0

上一篇:as入门

下一篇:原翻翻(合集篇,待续)

给主人留下些什么吧!~~