月度归档:2009年07月

Sed学习笔记

  sed [-n] program [file-list]
  sed [-n] -f program-file [file-list] 1.2参数
  略 1.3 选项
  –file program-file    -f program-file    指定文件中sed程序可以命令行上使用多次
  –in-place[=suffix]    -i [suffix]      就地编辑文件,把输出送到原来的文件中,并备份原来文件加后缀suffix
  –help                概述sed的用法
  –quiet或–silent    -n        除非使用print指令或标志来指定否则不会将文本行复制到标准输出 1.4 编辑器基础
  sed程序由符合如下语法的一行或多行命令构成
  [address[address]] instruction [argument-list]
  address是可选的,如省略,那么sed将对输入中的所有行进行处理
  instruction是用于改变文本的指令address用来选定行instruction来处理
  argument-list中参数的数目和类型取决于指令instruction
  如果想把多个sed命令放在同一行,可以使用;   1.4.1 地址
    行号作为地址可以用来选择某一行,$表示输入中的最后一行
    正则表达式作为地址,可以选中与之相匹配字符串的行
    sed可以使用除反斜杠和换行符之外的任意字符来定界
    如指定一个地址sed将选择该地址匹配行
    如指定二个地址,第一个地下选择行首,第二个选择匹配这下一行
  
  1.4.2 指令
    d    删除指令:导致sed不输出被选择行,并且不继续完成对该行的后续处理过程,sed执行删除后,它将从输入读取下一行,并从program或program-file中的第1条命令开始执行     n    下一条指令:输出当前选择的行,然后从输入中读下一行,并从program或program-file中的下一条命令开始对新读入的行进行处理     a    追加指令,在当前选择的行后插入一行或多行文本,如果有两个地址,那将在选定的每一行之后添加文本,如没有地址,则加入到所有行后
    例:[address[address]] a
      text
      text
      …….
      text
    除最后一行外,所添加的文本每一行都必须以反斜杠结尾。sed总是会输出所添加的文本,而不论命令行中是否使用-n 甚至在删除被添加了文本的那一行后。被增加的文本仍会输出     i    插入指令:与append相同,只是将文本添加到选定行之前     c    修改指令:与append类似,不同的是他将选定改为新文本     p    打印指令:将选中行写入标准输出,写入立即发生,不会反映后续指令执行结果     w file  写指令:与print类似,它将输出写入到指定文件中     r file    读指令:读出指定文件的内容并添加到选定行之后     q    退出指令:使sed立即结束     s    sed中的替换指令与vim中的类似
        [address[address]]s/pattern/replacement-string/[g][p][w file]
        可以在replacement-string中使用&,代表当前匹配的字符串   1.4.3 控制结构
    !    使sed后面与其同一行的指令作用于没有被该命令选中的每一行
        例:3!d表示删除除第3行外所有行
          $!p 显示除最后一行外的所有行     {}    指令组:一旦使用一对花括号将一组指令括起来,则这组指令将作用于它前要的地址选定行,使用; 可将多条命令分开     分支指令 sed 的info中指出,Sed并不宜使用分支,建议用awk或perl
    :label  标识sed程序中一个位置,标号label作为跳转目标     b[label]  无条件转移到label处:如没有指定分支目标,则跳过当前行中剩下的指令并从输入中读取下一行     t[label]  如果最近从输入中读取的行使得substitnte指令匹配成功,则到label处, 如没有指定分支目标,则跳过当前行中剩下的指令并从输入中读取下一行   1.4.4 Pattern区与Hold区
    sed中有两个缓冲区,所有的命令都是工作在pattern区的,pattern区中保存着sed刚刚从输入中读取的行,作为临时缓冲区,Hold区可以在操作Pattern区中数据时来暂存数据,在将数据放入Hold之前,它是空的
    关于Pattern区与Hold区之间的数据传送
    g  将Hold区内容复制到Pattern区中,Pattern区中原来的内容丢失
    G  将一个换行符与Hold区中的内容追加到Pattern区中内容之后
    h  将Pattern中内容复制到Hold中,Hold中原来的内容将丢失
    H  将一个换行符与Pattern区中的内容追加到Hold区中内容之后
    x  将Pattern 区与Hold区做交换 1.5 示例
  例1: [root@redhat test]# cat new
    Line one.
    The second line.
    The third.
    This is line four.
    Five.
    This is the sixth sentence.
    This is line seven.
    Eighth and last.
    [root@redhat test]# sed '/line/ p' new
    Line one.
    The second line.
    The second line.
    The third.
    This is line four.
    This is line four.
    Five.
    This is the sixth sentence.
    This is line seven.
    This is line seven.
    Eighth and last.
    [root@redhat test]# sed -n '/line/ p' new
    The second line.
    This is line four.
    This is line seven.
    除非特别指出,否则sed将在标准输出上输出所有的行,无论它是否被选定。当在命令行中使用-n选项时,sed仅仅在标准输出上输出特] ]>

bash中的字符串处理

bash中的字符串处理
  1 得到字符串长度
    [root@redhat test]# s=abcdef
    [root@redhat test]# expr length $s
    6
    [root@redhat test]# echo ${#s}
    6
    [root@redhat test]# expr "$s" : ".*"
    6

  2 查找子串
    [root@redhat test]# expr index $s a
    1
    [root@redhat test]# expr index $s b
    2
    [root@redhat test]# expr index $s c
    3
    [root@redhat test]# expr index $s d
    4
    [root@redhat test]# expr index $s e
    5
    [root@redhat test]# expr index $s f
    6
    [root@redhat test]# expr index $s g
    0

  3 得到子字符串
    语法1:expr substr startpos length 第一个字符序号为1
    [root@redhat test]# expr substr $s 1 3
    abc
    [root@redhat test]# expr substr $s 1 11
    abcdef
    [root@redhat test]# expr substr $s 3 4
    cdef
    [root@redhat test]# expr substr $s 3 1
    c
    [root@redhat test]# m=1
    [root@redhat test]# j=2
    [root@redhat test]# expr substr $s $m $j

    语法2:${x:pos:length} 第一个字符的序号为0
    [root@redhat test]# expr ${s:0:1}
    a
    [root@redhat test]# expr ${s:2:2}
    cd
    [root@redhat test]# expr ${s:2:11}
    cdef
    [root@redhat test]# m=1
    [root@redhat test]# j=2
    [root@redhat test]# expr ${s:$m:$j}
    bc

  4 匹配正则表达式
    [root@redhat test]# expr match $s "ab"
    2
    [root@redhat test]# expr match $s "abc"
    3
    [root@redhat test]# expr match $s "bc"
    0

  5 修改字符串掐头去尾
    #  去除最小匹配前缀
    ##  去除最大匹配前缀
    %  去除最小匹配后缀
    %%  去除最大匹配后缀
    [root@redhat test]# x=cccdddcccpicxxyyyxxx
    [root@redhat test]# echo ${x%x*x}
    cccdddcccpicxxyyyx
    [root@redhat test]# echo ${x%%x*x}
    cccdddcccpic
    [root@redhat test]# echo ${x#c?c}
    dddcccpicxxyyyxxx
    [root@redhat test]# echo ${x#c*c}
    cdddcccpicxxyyyxxx
    [root@redhat test]# echo ${x#c*c}
    cdddcccpicxxyyyxxx
    [root@redhat test]# echo ${x##c*c}
    xxyyyxxx
    这里正则用的特殊符号是? * 并非 . *

  6 字符串替换
    [root@redhat test]# x=efefefef
    [root@redhat test]# echo ${x/e/f}
    ffefefef
    [root@redhat test]# echo ${x//e/f}
    ffffffff
    [root@redhat test]# x=efefacacefacefcb
    [root@redhat test]# echo ${x//ef/f}
    ffacacfacfcb
    [root@redhat test]# echo ${x/ef/f}
    fefacacefacefcb
    [root@redhat test]# echo ${x/e??/f}
    ffacacefacefcb
    [root@redhat test]# echo ${x//e??/f}
    ffacacfcfb
    [root@redhat test]# echo ${x/f*/z}
    ez
    这里正则用的特殊符号是? * , 不可以使用 regexp

gawk 模式处理语言 学习笔记

gawk 模式处理语言
特性:
  1 灵活的格式  2 条件执行  3 偱环语句  4 数值变量
  5 字符串变量  6正则表表式  7关系表达式  8 c语言printf
  9 协进程    10 网络数据交换

1.1 语法
  gawk [options][program][file-list]
  gawk [options] -f program-file [file-list]
  gawk可以从指定文件中或标准输入获取输入
  使用getline可以对输入有更多选择
  协进程(coprocess)可以使gawk与另一个程序进行交互或通过网络交换数据

1.2 参数
  参数中的program是用户在命令行中所包含有gawk的程序
  program-file是存放gawk程序的文件
  在命令行上使用gawk要加单引号
  file-list是输入文件如不指定,则由标准输入,getline或协进程获取

1.3 选项
  –field-seperator fs      -F fs        将fs作为输入字段分隔符的值
  –file program-file      -f program-file    存放gawk程序
  –help          -W help      总结如何使用gawk
  –lint            -W lint      对不正确或不利于移植的结构发出警告
  –posix          -W posix      运行POSIX兼容版的gawk
  –traditional        -W traditional    忽略gawk中的新特性与awk兼容
  –assign var=value      -v var=value    给变量赋值

1.4 注意
  很多linux将/bin/awk链接到了/bin/gawk上

1.5 语言基础
  gawk 程序由一行或多行文本构成,其中包含一个模式和动作
  pattern {action}
  模式(pattern)用来从输入中选取文本行,对于模式选中的每行文本,都执行相应的对作
  如程序中不包含模式,gawk将选取所有行,如果不包含动作gawk将把选中的行复制到标准输出

  1.5.1 模式
    用斜杠把正则表达式包装起来,就可以作为模式使用
    ~操作符测试是否匹配正则表达式 !~测试不匹配
    用||或 &&来组合任何模式
    关系操作符包括:<,>,<=,>=,=,!=
    BEGIN与END是两个独特的模式分别是在gawk开始处理之前与处理之完毕之后的命令
    ,逗号,用逗号隔开的两个模式将选取匹配第一个模式行到匹配第二个模式的下一行

  1.5.2 动作
    gawk如果匹配某个模式,它将执行指定动作,如果没有指定动作,那将执行默认(可用{print}表示)如在print后带上参数,gawk将只显示指定参数。可将print输出发送到文件>追加>>或者通过管道发纷呈另一个程序|
    协进程|& 是一个双向的管道,可以与运行在后台的程序交换数据
    逗号用于print命令中把各项区分开
    通过分号可将多个动作隔开,可以在一行上包含多个动作。

  1.5.3 注释
    #是gawk的注释符号

  1.5.4 变量
    gawk的模式部分与动作部分中均可以使用用户变量与程序变量
    $0      当前记录
    $1-$n    当前记录中的字段
    FILENAME  当前输入文件名
    FS      输入字段的分隔符
    NF      当前记录的字段数目
    NR      当前记录的编号
    OFS      输出字段分隔符
    ORS      输出记录分隔符
    RS      输入记录分隔符

  1.5.5 函数
    length(str)      返回str中的字符数,如没参数,返回当前记录字符数
    int(num)        返回 num的整数部分
    index(str1,str2)    返回str2在str1中出现的位置,如不存在返回 0
    split(str,arr,del)    以del做分隔符,将str中的元素放到数组 arr中,返回个数
    sprintf(fmt,args)    根据fmt格式化args并返回格式化后的字符串
    substr(str,pos,len)    返回str 中从pos开始长度为len个字符的字符串
    tolower(str)      返回str副本,并转成小写字母
    toupper(str)      返回str副本,并转成大写字母

  1.5.6 算术操作符
    *,/,%,+,-,=,++,–,+=,-=,*=,/=,%=

  1.5.7 关联数组
    语法:array[string]=value
    可以将特殊的for结构用于关联数组
    语法如下:
    for (elem in array) action
    在for 遍历数组元素时,elem表示数组中每个元素的值,array为数组名称action为gawk对数组中每个元素所采取的动作,可以在action中使用elem变量。详细见1.6节

  1.5.8 printf
    可以使用printf来代替print控制gawk的输出,gawk版的printf类似于 C
    语法:printf "control-string",arg1,arg2,…,argn
      control-string决定了printf如何格式化arg
      可以在contral-string中使用/n来表示换行符,/t表示TAB
      control-string包含了转换规格,每个参数对应一个转换规格语法
      %[-][x[.y]]conv
      其中-使printf将参数左对齐,x表示最小字段宽度
      .y表示数字中小数点右边的位数,conv表示数值转换的类型
      conv        转换类型
      d      十进制
      e      指数表示
      f      浮点数字
      g      使用f或e中较短的那个
      o      无符号八进制
      s      字符串
   &nb

sp;  x      无符号十六进制

  1.5.9 控制结构
    1 if…else
      语法:(else可选)
        if (condition)
          {commands}
        [else
          {commands}]
      例1:if ($5<=5000) print $0
      例2:cat ifl
        BEGIN {
            nam="sam"
            if (nam=="max")
              print "name is max"
            else
              print "name is not max,it is",nam
            }
          gawk -f ifl

    2 while
      语法:while (condition)
          {commands}
      例:cat wh
        BEGIN {
            n=1
            while (n<=5)
              {
                print n"^2",2**n
                n++
              }
            }
        gawk -f wh

    3 for
      语法:for (init;condition;increment)
          {commands}
      例:cat forl
        BEGIN {
            for (n=1;n<=5;n++)
              print n"^2",2**n
            }
        gawk -f forl

      关联数组的for结构
      语法:
        for (var in array)
          {commands}
      例:END {for (name in manf) print name,manf[name]}
      对于关联数组的for 见1.6

    4 break
      结束for或 while最内层循环

    5 continue
      将for 或 while转移到末尾,并断续执行下一次迭代

1.6 示例
  建立一个示例文件 文件包括制造商,型号,生产年代,千里里程数及价格
  cat cars
  plym  fury      1970  73  2500
  chevy  malibu    1990  60  3000
  ford    mustang    1965  45  10000
  volvo  s80      1998  102  9850
  ford    thundbd    2003  15  10500
  chevy  malibu    2000  50  3500
  bmw  325i      1985  115  450
  honda  accord    2001  30  6000
  ford    taurus    2004  10  17000
  toyota  rav4      2002  180  750
  chevy  impata    1985  85  1550
  ford    explor    2003  25  9500
  

例1:
[root@redhat Testsh]# awk '{print}' cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
这是一个缺失模式,因为没有模式,gawk把输入中所有行复制到了输出

例2:
[root@redhat Testsh]# awk '/chevy/' cars
chevy malibu 1990 60 3000
chevy malibu 2000 50 3500
chevy impata 1985 85 1550
缺失模式,只有一个模式,但没有明确动作。斜杠指出chevy是一个正则表达式。在这种情况中将执行默认动作print.将输入中包含chevy的文本行复制到输出
注意:单引号可以阻止某此问题的发生(比如命令行由bash扩展了,导制传递给awk的参数出错)

例3:
[root@redhat Testsh]# awk '{print $3,$1}' cars
1970 plym
1990 chevy
1965 ford
1998 volvo
2003 ford
2000 chevy
1985 bmw
2001 honda
2004 ford
2002 toyota
1985 chevy
2003 ford
显示第三个字段与第一个字段

例4:
[root@redhat Testsh]# gawk '/chevy/ {print $3,$1}' cars
1990 chevy
2000 chevy
1985 chevy
显示包含chevy行的第三个字段与第一个字段

例5:
[root@redhat Testsh]# awk '/h/' cars
chevy malibu 1990 60 3000
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
honda accord 2001 30 6000
chevy impata 1985 85 1550
显示包含字母h的行

例6:
[root@redhat Testsh]# gawk '$1~/h/' cars
chevy malibu 1990 60 3000
chevy malibu 2000 50 3500
honda accord 2001 30 6000
chevy impata 1985 85 1550
显示第一个字段包含h的行

例7:
[root@redhat Testsh]# gawk '$1~/^h/' cars
honda accord 2001 30 6000
显示第一个字段第一个字母是h的行

例8:
[root@redhat Testsh]# gawk '$2~/^[tm]/ {print $3,$2,"$"$5}' cars
1990 malibu $3000
1965 mustang $10000
2003 thundbd $10500
2000 malibu $3500
2004 taurus $17000
选中第2个字段以t或m开头的行,并显示第3个字段和第2个字段, 1个美元符号以及第5个字段

例9:
[root@redhat Testsh]# gawk '$3~/5$/ {print $3,$1,"$"$5}' cars
1965 ford $10000
1985 bmw $450
1985 chevy $1550
$使用的三个作用,5$是对行尾或字段尾进行匹配,$加数字的方式表示某字段,"$"代表它自己

例10:
[root@redhat Testsh]# gawk '$3==1985' cars
bmw 325i 1985 115 450
chevy impata 1985 85 1550
显示第三个字段为1985的行

例11:
[root@redhat Testsh]# awk '$5<=3000' cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
bmw 325i 1985 115 450
toyota rav4 2002 180 750
chevy impata 1985 85 1550
列出字段5小于等于3000的行

例12:
[root@redhat Testsh]# awk '$5>2000 && $5<9000' cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
chevy malibu 2000 50 3500
honda accord 2001 30 6000
列出$5数值是2000与9000之间的行

[root@redhat Testsh]# awk '$5>"2000" && $5<"9000"' cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
toyota rav4 2002 180 750
列出$5数值是2000与9000之间的行,但由于2000与9000加了双引号,即进行正文比较(使用ASCII比较)

例13:
[root@redhat Testsh]# awk '/volvo/,/bmw/' cars
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
选中由逗号之前的模式指定的行致逗号之后模式匹配的行,如果没有匹配逗号之后的文本行,则会将选取到输入末尾

[root@redhat Testsh]# cat cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500

[root@redhat Testsh]# awk '/chevy/,/ford/' cars
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
chevy impata 1985 85 1550
ford explor 2003 25 9500
上边例子在找到第一组文本行之后,它将再次进行处理,查找匹配逗号异军突起前的文本行。awk查找落入chevy和ford之间的所有的三组文本行。尽管输入的每5行包含ford,但gawk并没有选择它,因为此时它正在处理第5行,正在搜索chevy

例14:
[root@redhat Testsh]# cat awk_t
BEGIN {print "make model year miles pricen"}
{print}

[root@redhat Testsh]# awk -f awk_t cars
make model year miles price

plym fury 1970 73 2500
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
一个简单的用-f 参数指定 awk程序文件的例子

例15: (length的使用)
[root@redhat Testsh]# awk '{print length"t",$0}' cars|sort -n
21 bmw 325i 1985 115 450
22 plym fury 1970 73 2500
23 volvo s80 1998 102 9850
24 ford explor 2003 25 9500
24 toyota rav4 2002 180 750
25 chevy impata 1985 85 1550
25 chevy malibu 1990 60 3000
25 chevy malibu 2000 50 3500
25 ford taurus 2004 10 17000
25 honda accord 2001 30 6000
26 ford mustang 1965 45 10000
26 ford thundbd 2003 15 10500
此例使用了length函数来显示每行的字符个数,t是一个TAB,用来对齐
sort -n 对数字进行排序

例16:(NR的意义:行编号)
[root@redhat Testsh]# awk 'length>24 {print NR"t",$0}' cars
2 chevy malibu 1990 60 3000
3 ford mustang 1965 45 10000
5 ford thundbd 2003 15 10500
6 chevy malibu 2000 50 3500
8 honda accord 2001 30 6000
9 ford taurus 2004 10 17000
11 chevy impata 1985 85 1550
显示出字符个数大于24的行,并显示行号

例17:
[root@redhat Testsh]# awk 'NR==2,NR==4' cars
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
显示从第二行到第四行
例18: (END的使用)
[root@redhat Testsh]# awk '{print}END{print "—END—"}' cars
plym fury 1970 73 2500
chevy malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevy malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevy impata 1985 85 1550
ford explor 2003 25 9500
—END—
在处理完输入之后才执行END指定的语句

例19:
[root@redhat Testsh]# cat awk_t1
{
if ($1~/ply/) $1="plyssj"
if ($1~/chev/) $1="chevssj"
print
}
[root@redhat Testsh]# awk -f awk_t1 cars
plyssj fury 1970 73 2500
chevssj malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevssj malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevssj impata 1985 85 1550
ford explor 2003 25 9500
给$1赋值的例子

例20:(建立独立的awk脚本)
[root@redhat Testsh]# cat if.ak
#!/bin/awk -f
{
if ($1~/ply/) $1="plyssj"
if ($1~/chev/) $1="chevssj"
print
}
[root@redhat Testsh]# if.ak cars
plyssj fury 1970 73 2500
chevssj malibu 1990 60 3000
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
chevssj malibu 2000 50 3500
bmw 325i 1985 115 450
honda accord 2001 30 6000
ford taurus 2004 10 17000
toyota rav4 2002 180 750
chevssj impata 1985 85 1550
ford explor 2003 25 9500

例21:(printf的使用)
[root@redhat Testsh]# cat if1.ak
#!/bin/awk -f
BEGIN{
print " Miles"
print "Make Model year (000) price"
print "——————————————-"}
{if ($1~/ply/) $1="plyssj"
if ($1~/chev/) $1="chevssj"
printf "%-10s %-8s %-5d %-5d $ %8.2fn",$1,$2,$3,$4,$5
}
[root@redhat Testsh]# if1.ak cars
Miles
Make Model year (000) price
——————————————-
plyssj fury 1970 73 $ 2500.00
chevssj malibu 1990 60 $ 3000.00
ford mustang 1965 45 $ 10000.00
volvo s80 1998 102 $ 9850.00
ford thundbd 2003 15 $ 10500.00
chevssj malibu 2000 50 $ 3500.00
bmw 325i 1985 115 $ 450.00
honda accord 2001 30 $ 6000.00
ford taurus 2004 10 $ 17000.00
toyota rav4 2002 180 $ 750.00
chevssj impata 1985 85 $ 1550.00
ford explor 2003 25 $ 9500.00
例22:(重定向输出)
[root@redhat Testsh]# cat awk_out
/chevy/ {print > "chevfile"}
/ford/ {print > "fordfile"}
[root@redhat Testsh]# awk -f awk_out cars
[root@redhat Testsh]# cat chevfile;echo "";cat fordfile
chevy malibu 1990 60 3000
chevy malibu 2000 50 3500
chevy impata 1985 85 1550

ford mustang 1965 45 10000
ford thundbd 2003 15 10500
ford taurus 2004 10 17000
ford explor 2003 25 9500

例23:(使用FS )
[root@redhat Testsh]# cat find_uid
#!/bin/awk -f
BEGIN{FS=":"
saveit=0}
$3>saveit {saveit=$3}
END{print "Max UID is " saveit }
[root@redhat Testsh]# find_uid /etc/passwd
Max UID is 65534
[root@redhat Testsh]# awk -F: '{print $3}' /etc/passwd |sort -n|tail -5
556
557
558
559
65534

例24:
[root@redhat Testsh]# cat manuf
#!/bin/bash
gawk '{manuf[$1]++} END {for (name in manuf) print name,manuf[name]}' cars |sort
[root@redhat Testsh]# bash ./manuf
bmw 1
chevy 3
ford 4
honda 1
plym 1
toyota 1
volvo 1
关联数组使用cars文件中每条记录的第1个字段的内容作为索引。这个数组由元素manuf[plym],manuf[chevy]等组成。每个元素在创建时都被初始化为0

例25:
[root@redhat Testsh]# cat word_usage
#!/bin/bash
tr -cs '[a-zA-Z]' '[n*]' < $1|gawk '{count[$1]++}END {for (item in count) printf "%-15s %-4d n", item,count[item]}'|sort +1nr +0f -1
[root@redhat Testsh]# bash ./word_usage text.txt |head -5
the 64
is 35
of 28
a 21
and 21
……
显示文件中单词的使用情况列表

例26:
[root@redhat Testsh]# cat report
#!/bin/bash
if [ $# == 0 ] ;then
echo "you must supply a filename"
exit 1
fi
(date;cat $1)|awk '
NR==1 {print $6,$2,$3,$4}
NR>1 {printf "%-10s%-15sn", $5,$1}'
[root@redhat Testsh]# bash ./report cars
2009 7月 30 10:55:07
2500 plym
3000 chevy
10000 ford
9850 volvo
10500 ford
3500 chevy
450 bmw
6000 honda
17000 ford
750 toyota
1550 chevy
9500 ford
一个把日期加入报告中的办法
getline与协进程先不讨论了,一般用不到

练习:
1 编写一个gawk程序对文件中的每行编号,然后将它的输出发送到标准输出
[root@redhat root]# cat g4
{print NR,$0
}
[root@redhat root]# cat tt
aaaa 1111
bbbb 2222
cccc 3333
dddd 4444
[root@redhat root]# gawk -f g4 <tt
1 aaaa 1111
2 bbbb 2222
3 cccc 3333
4 dddd 4444

2 编写一个gawk程序,显示第1个字段中的字符数目,后面跟着第1个字段,然后将输出发送到标准输出
[root@redhat root]# cat g5
{print length($1),$1
}
[root@redhat root]# cat tt
aaaa 1111
bbbb 2222
cccc 3333
dddd 4444
[root@redhat root]# gawk -f g5 <tt
4 aaaa
4 bbbb
4 cccc
4 dddd

3 编写一个gawk程序,使用cars文件,显示所有价格高于5000美元的汽车,然后将其输出发送到标准输出
[root@redhat root]# awk -f g5 < /root/Testsh/cars
ford mustang 1965 45 10000
volvo s80 1998 102 9850
ford thundbd 2003 15 10500
honda accord 2001 30 6000
ford taurus 2004 10 17000
ford explor 2003 25 9500

4 使用gawk来判断/etc/termcap中有多少行包含了字符串vt100.使用grep验证一下自己的程序
[root@redhat root]# cat g5
{if ($0~/vt100/)
num+=1
}
END{print num}
[root@redhat root]# time awk -f g5 /etc/termcap
174

real 0m0.142s
user 0m0.140s
sys 0m0.010s

验证:

[root@redhat root]# time grep -c vt100 < /etc/termcap
174

real 0m0.317s
user 0m0.310s
sys 0m0.010s

还是awk比较快

正则表达式 学习笔记

正则表达式
前言:ed vim emacs grep gawk sed等工具使用的正则表达式,这些表达式与shell的模糊文件引用中使用的正则表达式是不同的

A1 字符
   字符是除换行之外的其他任意字字符。正则表达式中的大多数字符代表它们自身,而那些不代表自身的字符称为特殊字符。如果需要特殊字符代表自身,那么就需要将这些字符转义。

A2 定界符
  正则表达式使用 / 作为定界符,vim中允许使用其它定界符,而grep不使用任何定界符。在一些含义不模糊的情况下,第2个定界符不是必要的。例如,当第2个定界符后面要紧跟RETURN时,就可以省略第2 个定界符

A3 简单字符串
最基本的正则表达式是只包含非特殊字符和定界符的简单字符串。简单字符串只与它自身匹配
正则表达式  匹配字符串  示例
/ring/  ring  
/Thursday/  Thursday  
/or not/  or not  

A4 特殊字符
  正则表达式中使用特殊字符可以使得正则表达式匹配多个字符串

  A4.1 句点
  /.alk/ 句点匹配任意单个字符,该字符不能为空

  A4.2 方括号
  /[bB]ill/  与bill和Bill匹配
  /t[aeiou].k/  与t后跟元音字母匹配
  /# [6-9]/  与#后跟空格再跟6到9之间的数字的字符串匹配
  /[^a-zA-Z]/ 与26个字母之外的任意字符匹配

  A4.3 星号
  * 跟随在代表某个字符的正则表达式之后,表示与该正则表达式所匹配的 0个或多个匹配,跟在句点后的星号可以匹配任意字符串,字符定义类后跟星号可以匹配包含该类定义的成员字符的任意字符串
  /ab*c/  a后跟0个或多个b后再跟c的字符串匹配
  /ab.*c/ 与ab后跟0个或多个字符再跟c的字符串匹配
  /t.*ing/ 与t后跟0个或多个字任再跟ing的字符串匹配
  /[a-zA-Z]*/ 与由字母和空格组成的字符串匹配
  /(.*)/ 与圆括号括起来的最长字符串匹配
  /([^)]*)/ 与圆括号括起来的最短字符串匹配
  A4.4   脱字符与美元符号
    以脱字符开始的正则表达式只能匹配位于行首的字符串,以美元符号结尾的正则表    达式只能匹配行末尾的字符串
    /^T/  与位于行首的T匹配
    /^+[0-9]/ 与位于行且由加号后跟一个数字组成的字符串匹配
    /:$/ 与位于行尾的:匹配

  A4.5 转义特殊字符
    在特殊字符之前使用反斜杠可以转义除数字和圆括号外的特殊字符。
    /end./  与end后跟一个句点的字符串匹配
    /\/  与单独一个反斜杠匹配
    /*/ 与单独一个星号匹配
    /[5]/  与 [5]匹配
    /and/or/  与and/or匹配

A5 规则
  A5.1 最长匹配
    正则表达式总是与尽可能长的字符串匹配,从行的开始尽可能地向前匹配
    例如:This (rug) is not what it once was (a long time ago),is it?
    表达式/Th.*is/将匹配
    This (rug) is not what it once was (a long time ago),is
    表达式/(.*)/将匹配
    (rug) is not what it once was (a long time ago)
    表达式/([^)]*)/将匹配
    (rug)
  
  A5.2 空正则表达式
    对于某此工具例如vim 和less,但对于grep不适用,空正则表达式代表上次使用的表达式。例如在vim 中使用下面的替换命令
    :/s/mike/robert
    如要再次使用该替换可以使用下面的
    :s//robert/
    或者
    先查找mike串,再进行替换
    /mike/
    :s//robert/
    其中的空正则表达式(//)代表上次使用的正则表达式(/mike/)

A6 括号表达式
  使用转义圆括号可以将下则表达式括起来。但并不会改变匹配效果例如下例
  /a(b*)c/与/ab*c/是一样的

A7 替换字符串
  A7.1 &符号
    在替换字符串中&代表搜索字符串所匹配的字符串的值,例
    在文件 123 123 456 567使用:s/[0-9][0-9]*/(&)
    结果是(123) (123) (456) (567)

  A7.2 转义数字
    last-name, first-name initial
    转成first-name initial last-name

    :1,$s/([^,]*), (.*)/2 1/

A8 扩展的正则表达式
  工具egrep,带-E的工具grep,和gawk
  我没找到用的地方,先不细写了,用到了再加上
  redhat vi,grep都用不了

A9 小结
正则表达式中的特殊字符
.  与单个字符匹配
*  与*前边一个字符的0个或多个匹配
^  与行的开始匹配,在[]中表示不包括在类中
$  与行的末尾匹配
  用来转义的
<  与字的开始匹配
>  与字的末尾匹配

扩展正则

替换字符串
&  代表匹配的字符串
n  转义n代表第n个被括号正则表达式所匹配的字符串

Redhat Linux 9 学习笔记 (未完……)

第二章

2.1 开机
  linux引导程序GRUB/LILO加载内核linux kernel
  启动日志的位置 /var/log/dmesg
  执行/sbin/init 这是执行启动程序与script
  执行/etc/rc.d/rc.sysinit 脚本.(初始化相关)
  执行/etc/init 根据 /etc/inittab的内容选择“执行层级”
    0 关机 1 单用户 2 多用户无网络文件系统 3 完整的多用户多任务文字接口
    4 Runlevel 5完整的多用户多任务X11图形接口 6 重新开机
  由init 执行默认Runlevel目录中所有Scripts(/etc/rc.d/rc?.d)
  执行/etc/rc.d/rc.local 此处加入自己的脚本
  执行/bin/login
  打开登陆画面(根据Runlevel打开文字接口哎呀图形接口)
  Runlevel环境Rc?.d里有S开头和K开头的数值越小越早执行
  
  无法开机时的处理
    /boot/grub/grub.conf 或 /etc/lilo.conf 文件设置错误
    文件系统设置文件/etc/fstab设置错误
    系统init启动文件/etc/inittab设置错误,例如使用错误runlevel等
    以上问题均可用引导盘解决
    利用mkbootdisk命令制作引导盘
    uname -r 查询内核版本

2,2 关机
  将关机信息写在/etc/motd中,用户登陆后就可以看到
  在关机前最好先使用sync命令,将缓存写回硬盘

  shutdown 常见用法
    shutdown -k 5 /attention:system will shutdown系统5分钟后关闭,实际不执行只提示
    shutdown 2 attention:system will shutdown系统2分钟后进入单用户维护模式
    shutdown -h now 立刻关机
    shutdown 9:30 系统9:30分进入单用户维护模式
    shutdown +5 系统5分钟后进入单用户维护模式
    shutdown now 立刻进入单用户维护模式
    shutdown -r 9:30 系统在9:30分重新开机
    以上方法CTRL+C可以取消
    halt poweroff reboot 关机

2.3 系统登陆

  命令 su – 可以登陆到root并改变目录到root
  /etc/nologin文件可以禁止除root以外的用户无法登陆
  系统注销 logout

2.4 Vim 编辑器
  1进入编辑模式
    i 插入 a 增加 o 插入新行
  2 移动光标
    数字0 移至该行的行首
    G 最后一行行首
    $ 该行行尾
    { 向前一个段落
    } 向后一个段落
    ~ 改变大小写
  3 复制文字
    yy 复制一行
    yw 复制一个字
    数+yw 当前和后面几个字一起复制
    数+yy 当前行和后面几行一起复制
    p 粘贴
  4 删除文字
    d+方向键(上下左右)
    dd 删除当前行
    dw 删除当前所在字
    数+dd 删除本行以及下方的行共N行

    D 删除同行中光标后所有字符
    x 删除光标后所有字符
    数+x 删除光标与后方共N个字符
    数+X 删除光标前方共N个字符
  5 其它用法
    ctrl+g  显示总行数与当前所在行
    数+G  跳到指定的行
    r    取代字符
    R    一直取代直到按下ESC
    u    复原
    U    取消对行所做的所有改变
    .    重复上一个命令
    ZZ    保存并退出
    %    检查括号对应
    c+数+w  删除指定数目的字
  6 last line mode 下的命令
    e+文件名  建立一个文件
    n+文件名  加载另一文件
    w      保存
    ?字符串    向上查找n断续
    q      退出
    q!      强行退出
    wq      存盘并退出
    set nu    在每行行首加入行号
    set nonu    取消行号
    数+回车    光标移至该行
    /字符串    向下查找字符串

第三章 文件系统管理

3.3 创建文件系统
  fdisk /dev/装置名称
  fdisk -s /dev/sda 看硬盘大小
  fdisk -l 看信息
  m 帮助 L文件系统值 d 删除分区
  1 p查看当前情况
  2 n 加入分区
  3 t 选分区类型
  4 w 保存并退出 q退出不保存
  5 格式化 mkfs -t ext3 /dev/sda1
  6 创建加载路径 mkdir /test
  7 加载分区 mount /dev/sda1 /test
  8 自动加载 /etc/fstab
    /dev/sda1    /test    ext3    defanlts    1    2

3.4 文件系统的基本命令操作
  1 显示目前工作目录 pwd
  2 ls
    -l 显示详细信息,每行一个
    -a 显示所有文件
    -A 显示所有不包括 . ..
    -c 以更改时间排序
    -h 以K,M,G显示文件大小
    -H 同上单位 1000
    -i 显示inode号
    -L 显示原始链接信息
    -m 用 , 分隔文件名
    -n 用户识别码和组训别码替换名称
    -o 不列组名
    -r 反向排序
    -R 递归
    -s 显示大小以块为单位
    -S 用文件与目录大小排序
    -t 用变动时间排序
    -u 以最后存取时间排序
    -U 不排序
    -v 版本排序
    -X 最后扩展名排序
    –full-time 显示完整时间
    -F 在文件后边加符号
    
  3 目录切换 cd

  4 cp mv rm
    cp:复制
      -a  与-dpR相同
      -b  删除,覆盖之前先备份
      -d &

nbsp;如有链接,复制链接
      -f  强行复制
      -i  覆盖之前先询问
      -l  建立硬链接
      -p  保存来源的属性
      -r(R)  递归
      -s  建立符号链接
      -S  修改备份字符串
      -u  比较更新
      -v  显示执行过程
      -x  处理同一文件系统
    mv:移运与更名
      -b  -f  -i  -S  -u  -v 意义同上
    rm:删除文件
      -d  直接删除硬件连接数会导致辞必须用fsck检查磁盘
      -f  -i  -r  -v  意义同cp
例:cp -ax /test1 /test2  复制目录树

  5 目录新增与删除 mkdir rmdir
    例:  mkdir /test 建立test目录
      rm -rf /test 删除整个目录树
      rmdir /fax 只能是空目录

  6 创建链接文件 ln
    -b  删除前先备份
    -d  指定目录的符号的硬链接(实际为软链接的硬链接)
    -f  强行建立硬链接
    -i  先询问
    -n  当文件对待
    -s  建立符号链接
    -S  备份字符串
    注意:硬链接不能用在目录上或跨扇区

  7 查看文件内容 cat
    -A  与-vET相同
    -b  在非空白行前加编号
    -e  与-vE相同
    -E  每行最后加上$
    -n  每行加编号包括空白行
    -s  当空白行超过一行,以一行显示
    -t  同-vT
    -T  TAB以"^I"表示
    -v  除换行和TAB以外,其它控制以^表示,高位用M-表示

  8 分页显示文件内容 more
    -s  连续空白行合并成一行
    -<行数>  指定每次显示的行数
    +/<字符串>  在文件中查找指定字符串
    +<行数>  从指定行数开始显示

  9 交互操作显示文件内容 less

  10 识别文件类型 file
    -f<>    指定名称文件
    -L    显示符号链接指向的类别
    -m<魔法数字文件>  /usr/share
    -z    尝试解读压缩文件内容

  11 输出文件内空前面与后面的部分 head tail
    head
      -c<显示数目>    byte计算
        b=512  k=1024  m=1048576
      -n<显示行数>    或 -<行数>
    tail
      同上
      +<数目>    从第几行到结尾

3.5 文件权限基本概念
  1 文件权限修改 chmod
    -R  递归
    -v   显示执行过程

  2 变更拥有者 chown
    -R 递归
    例:chown root.root /root/ssj

  3 指定文件默认权限屏蔽 umask
    -S以文本方式显示
      新建文件为0666    目录为0777    如屏蔽为0022
      0666-0022=0664=-rw-r–r–

3.6 I/O重新导向及管道
  1 linux的标准输入输出共有3种形态
    标准输入(stdin) 从键盘或文件
    标准输出(stdout) 输出到终端机或屏幕
    标准错误输出(stderr)
  
  2 输出导向 >
    例:ls -al /etc > /test1/etc.txt

  3 附加输出导向

  4 输入导向 <

  5 附加输入导向 <<
    自定义一个字符串,系统在收到此字符串前会持续地将数据输入文件
    例:#mail shashijie@qq.com << quit
      >test
      >quit
      #
  6 错误输出导向 &>

  7 管道 pipe
    将其它程序的输出结果当另一个程序的输入
    例: #ll /etc | less 或 #ll /etc | more

第四章 磁盘管理

4.1 磁盘管理基本命令与工具
  1 转换软盘数据—dd
    将软盘中的数据写成文件
      dd if=/dev/fd0 of=file
    文件写入软盘
      dd if=boot.img of=/dev/fd0 bs=1440k
    转换大小写 (小到大) ucase 小->大 lcase 大->小
      dd if=./text1 of=./test2 conv=ucase

  2 显示磁盘使用空间—du
    -a  显示所有文件大小
    -h  以K M G 显示大小
    -m  以1M为单位计算
    -s  仅显示总计

    例:[root@redhat Testsh]# du
      20 .
      [root@redhat Testsh]# du -ah
      4.0K ./Recursive.sh
      4.0K ./tmp.sh
      4.0K ./Fibonacci_while.sh
      4.0K ./Fibonacci_recursive.sh
      20K .
      [root@redhat Testsh]# du -am
      1 ./Recursive.sh
      1 ./tmp.sh
      1 ./Fibonacci_while.sh
      1 ./Fibonacci_recursive.sh
      1 .

  3 检查ext2文件系统 e2fsck
    -c    一并执行badblocks,检查是否有坏块
    -f    强制检查
    -F    先清缓冲区再检查
    -j&l

t;>    日志位置
    -t    时间信息
    -l<文件>  将文件中指定块加入损坏块列表
    -L    同步
    -n    只读 NO回答
    -y    yes回答
    -p    自动修复
    例:
      e2fsck /dev/sdc1  检查文件系统是否正确
      e2fsck -j ext3 -p /dev/sdc1  检查ext3文件系统正确性,并自行修复
      e2fsck -j ext3 -c /dev/sdc1  检查ext3正确性并执行badblocks以检查是否有损      毁块
      e2fsck -j ext3 -f /dev/sdc1  即使没有错误,也强制检查正确性
      e2fsck -j ext3 -f -t /dev/sdc1  同上+显示时间信息
      e2fsck -j ext3 -l badblockslist /dev/sdc1    检查正确性,并将badblockslist中指      定的块加到损毁块列表中
      e2fsck -L badblockslist /dev/sdc1  检查正确性,将损毁块列表设成与          badblockslist一致
      e2fsck -F /dev/sdc1    先清除缓冲区再检查
      e2fsck -y /dev/sdc1    非互动方式,以yes回答
      e2fsck -n /dev/sdc1    非互动方式,以只读方式检查,以NO回答
    返回值:0 无错误 1 发生错误并以修正 2 发生错误并修正如系统卸载须重启
        4 有错也没有修正 8 运行时发生错误 16 使用语法错 128共享函数错
  4 创建ext2文件系统—mke2fs
    -b  指定块大小
    -c  检查有无损毁块
    -F  不管设备强制mke2fs
    -i  指定inode块大小
    -j  建立ext3文件系统
    -N  指定inode数目
    -l<文件>    指定损毁块信息
    -L<标签>
    -m<百分比值>  指定给管理员保留的比例 默认5%
    -r   指定ext2文件系统版本
    -S  仅写入superblock与group descriptors
    -v  显示详细执行信息

4.2 系统加载—mount
    -a  加载/etc/fstab 中所有设备
    -o<选项>    exec 可执行二进制文件
          noexec 不可执行
          nouser  非管理员无法加载
          ro  只读
          rw  可读写
          remount  重新加载
    -r 只读加载
    -t<文件系统类型>

  卸载—umount

4.3 磁盘空间管理
  1 编辑 /etc/fstab
    例:LABEL=/home/home  ext3  defaults  usrquota,grpquota  1  2
      usrquota:限制用户使用空间
      grpquota:限制组使用空间
  
  2 重新开机
    或者使用: mount -o remount /dev/sdc1
    /etc/fstab 与 /etc/mtab

  3 执行 quotacheck
    -a  扫描/etc/fstab里加入quota设定的分区
    -c  不读取已存在的aquota库,重新扫描并存储
    -d  显示执行过程
    -g  扫描时,计算每个组所占用的目录和文件数并建立quota.group
    -m  强制执行
    -R  排除根目录所在分区,配合-a使用
    -u  计算每个用户所占用的目录和文件数目,并建立quota.user
    -v  显示过程

    例:quota -avguc

  4 edquota命令编辑aquota.group与aquota.user
    -g  设置组的空间限制
    -p  复制某用户或组的限制到另一用户或组
    -t  调协文件系统soft time限制
    -u  设置用户的quota(默认)
    例:edquota ssj  设置ssj的磁盘可用空间
      edquota -t  设置系统soft time(内定7days 可以是days,hours minutes,seconds)
      edquota -p root ssj    把root的空间限制复制给ssj
      edquota -p root -g grouptest    把root的空间限制复制给grouptest组
      edquota -g grouptest    设置组配额
  5 启动与关闭quota
    启动:quotaon
      -a  打开在/etc/fstab设定的
      -g  打开组的
      -u  打开用户的(默认)
      -v  显示执行过程
    例:quotaon -av  打开所有分区的限制
    
    关闭:quotaoff
      -a  关闭在/etc/fstab设定的
      -g  关闭组的
      -u  关闭用户的(默认)
      -v  显示执行过程

    查看限制:repquota
      -a  查看在/etc/fstab设定的
      -g  查看组的
      -u  查看用户的(默认)
      -v  显示执行过程
    例:repquota -augv | less

4.4 软驱的使用
  1 软盘的加载与卸载
    例:mount /mnt/floppy    (不需要指定设备名)

  2 软驱命令—mtools
    可以用盘符代替挂载点在/etc/mtools.conf中设置
    命令通过mtools 来看

  3 格式化
    例1:mformat a:
    例2:mke2fs /dev/fd0

4.5 光盘的使用
  1 加载:
    mount /mnt/cdrom

第五章 用户与组管理

5.1 用户与组

账号
  1 标准用户
  2 标准组

5.2 用户账号信息—/etc/passwd
  /etc/shadow 文件
  /etc/login.defs  设置安全原则,如最小长度等

5.3 组账号信息—/etc/group
  /etc/gshadow

5.4 使用useradd命令新增用户账号
  注意:增加前最好用finger命令查看账号是否存在
  1 增加用户:useradd
    -c<备注>  
    -d<登陆目录>
    -e<有效期限>      月份/日期/年后两位
    -f<缓冲天数>      过期后几天关闭
    -g          指定所属组
    -G          指定附加组
    -m          建立登陆目录
    -M          不建立登陆目录
    -n          不建立与用户名相同的组名
    -r          建立系统账号
    -s<shell>        指定所使用的shell
    -u          指定uid

  2 设置密码:passwd
    -d  删除密码(root可以删除所有人的)
    -f  强制执行与-u一起用
    -u  解开以已上锁的账号
    -k  只有在密码失效后方可更新
    -l  锁定账号(root可以用)
    -S  列出密码的相关信息
    例:passwd  变更自己的密码
    如要解开密码为空的用户,使用-u的同时要使用-f

  3修改账号内:usermod
    -c<备注>  
    -d<登陆目录>
    -e<有效期限>      月份/日期/年后两位
    -f<缓冲天数>      过期后几天关闭
    -g          指定所属组
    -G          指定附加组
    -u          指定uid

5.5 用户密码管理
  上边的passwd

5.6 新增组账号
  1 增加组:groupadd
    -f  强制建立
    -g  设定组识别码
    -o  强制使用重复的组识别码,与-g一起使用
    -r  建立系统组
  例:groupadd test
    groupadd -g 700 test

  2 修改组:groupmod
    -g  设定组识别码
    -n  设置组名
    -o  强制使用组识别码
  例:groupmod newname oldname

5.7 删除用户及组账号
  删除用户要格外小心要考虑到的事如下
  1 在/etc/passwd中删除用户记录
  2 在/etc/shadow中删除记录
  3 在/etc/group删除同名记录
  4 删除用户主目录
  5 删除电子邮件 /var/spool/mail/username
  6 删除用户执行的后台程序
    ps -aux | grep "test"
    kill pid
  7 删除用户crontab
    rm /var/spool/cron/username
    或 /usr/bin/crontab -u username -d
  8 删除组账号
    groupdel groupname

5.8 新增大量用户账号
  略

5.9 管理帐号常用命令
  1 显示自身的用户名
    whoami 或 id -un
  2 显示所有登陆用户信息—w
  3 显示所有登陆用户信息—who
    ami    与whoami相同
    -b    系统最近启动时间
    -d    显示已死掉的程序
    -i    显示闲置时间
    -q    显示总人数
    -r    显示当前执行等级

  4 搜寻并显示用户信息—finger
  5 改变finger的内容—chfn
    chfn ssj1
  6 传送信息到其它登陆用户—write
    write ssj3
    >who are you?
    CTRL+C

bash 内置命令 2.05b.0(1)

* .: 把SHELL脚本当作当前进程的一部分执行.
* :: 返回0或者true.
* [: Bourne Shell Builtins.
* alias: 别名.
* bg: 在后台放置一个挂起的任务.
* bind: Bash Builtins.
* break: 从一个循环控制结构中退出.
* builtin: Bash Builtins.
* cd: 改变到其它的工作目录.
* command: Bash Builtins.
* compgen: Programmable Completion Builtins.
* complete: Programmable Completion Builtins.
* continue: 直接转到循环的下一次迭代的开始处.
* declare: 声名变量.
* dirs: Directory Stack Builtins.
* disown: Job Control Builtins.
* echo: 显示出它后边的参数.
* enable: Bash Builtins.
* eval: 扫描并计算命令行.
* exec: 执行一个shell脚本或者程序并替换掉当前进程.
* exit: 从当前的shell中退出.
* export: 把一个变量的值放在被调用的环境中(输出变量).
* fc: Bash History Builtins.
* fg: 把一个在后台执行的程序提交到前台.
* getopts: 分析一个shell脚本的参数.
* hash: Bourne Shell Builtins.
* help: Bash Builtins.
* history: 查看执行命令的历史记录.
* jobs: 显示后台任务的列表.
* kill: 给一个进程或者作业发送一个信号.
* let: 数学计算后面的表达式的值.
* local: 声明局部变量.
* logout: 登出shell.
* popd: 目录栈出栈.
* printf: Bash Builtins.
* pushd: 目录栈入栈.
* pwd: 显示工作目录.
* read: 从标准输入中读入一行.
* readonly: 把一个变量名为只读.
* return: 返回值.
* set: 设置shell标志或命令行参数变量,如不加参数则列出所有变量.
* shift: 提升每个命令行参数.
* shopt: Bash Builtins.
* source: Bash Builtins.
* suspend: Job Control Builtins.
* test: 参数比较.
* times: 显示当前shell以及其子进程的运行时间.
* trap: 捕获一个信号.
* type: 显示出每个参数怎样被解释为一个命令.
* typeset: 声名变量同declare.
* ulimit: Bash Builtins.
* umask: 返回文件创建时的掩码值.
* unalias: 删除别名.
* unset: 删除一个变量或者函数.
* wait: 等待后台进程的结束.

以上是bash2.05b所有的内置命令,我把我知道的全译成中文解释了,不知道的待以后会了再加上

bash 递归算法 比较

一个阶乘的递归算法

#!/bin/bash
function recursive()
{
local i=$1
if [ $i -eq 0 ];then
num=1
else
recursive `expr $i – 1`
num=`expr $i * $num`
fi
return $num
}
recursive $1
echo $num

#!/bin/bash
function recursive()
{
local i=$1
if [ $i -eq 0 ];then
num=1
else
recursive $[ $i – 1 ]
num=$[ $i * $num ]
fi
return $num
}
recursive $1
echo $num

用循环语句来做阶乘

#!/bin/bash
if [ -z $1 ];then
echo "Need one parameter"
exit 1
elif [ $1 -gt 20 -o $1 -lt 1 ];then
echo "Number please Enter 1-20"
exit 1
fi
i=$1
num=1
until [ $i -eq 0 ]
do
let num=$num*$i
((i-=1))
done
echo $num

前两种只是写法上有所不同,其实是一样的,第三种加入了参数验证,使用起来更安全.
循环比递归开销小,递归代码量小但开销惊人,用哪种自己看着办吧
因为我的电脑是64位的,寄存器最大是可以放下2^64=18446744073709551616所以只能算到20的阶乘
看脚本的执行过程可以用bash -x ./xxxx.sh 5

习题(2)

把当前目录中的所有文件按inode的编号顺序排列,对显示出对应的文件名,把输出结果保存在文件中

ll -i | awk '{print $1,$9}' |sort > 123.txt