现在的位置: 首页 > 综合 > 正文

Linux Shell常用技巧

2014年01月18日 ⁄ 综合 ⁄ 共 4568字 ⁄ 字号 评论关闭

1.  
 变量:

    在awk中变量无须定义即可使用,变量在赋值时即已经完成了定义。变量的类型可以是数字、字符串。根据使用的不同,未初始化变量的值为0或空白字符串" ",这主要取决于变量应用的上下文。下面为变量的赋值负号列表:
    符号  
    含义           等价形式

    =         
a = 5          a = 5

  
 +=        a = a + 5    a += 5

  
 -=         a = a - 5     a -= 5

  
 *=        a = a * 5     a *= 5

  
 /=         a = a / 5     a /= 5

  
 %=       a = a % 5    a %= 5

  
 ^=        a = a ^ 5     a ^= 5

    
    />
awk '$1 ~ /Tom/ {Wage = $2 * $3; print Wage}' filename

    该命令将从文件中读取,并查找第一个域字段匹配Tom的记录,再将其第二和第三个字段的乘积赋值给自定义的Wage变量,最后通过print命令将该变量打印输出。
    
    />
awk ' {$5 = 1000 * $3 / $2; print}' filename

    在上面的命令中,如果$5不存在,awk将计算表达式1000 * $3 / $2的值,并将其赋值给$5。如果第五个域存在,则用表达式覆盖$5原来的值。
    
    我们同样也可以在命令行中定义自定义的变量,用法如下:
    />
awk -F: -f awkscript month=4 year=2011 filename

    这里的month和year都是自定义变量,且分别被赋值为4和2000,在awk的脚本中这些变量将可以被直接使用,他们和脚本中定义的变量在使用上没有任何区别。
    
    除此之外,awk还提供了一组内建变量(变量名全部大写),见如下列表:
    变量名  
              变量内容

    ARGC  
              命令行参数的数量。

  
 ARGIND             命令行正在处理的当前文件的AGV的索引。

  
 ARGV                 命令行参数数组。

  
 CONVFMT           转换数字格式。

  
 ENVIRON            从shell中传递来的包含当前环境变量的数组。

  
 ERRNO               当使用close函数或者通过getline函数读取的时候,发生的
重新定向错误的描述信息就保存在这个变量中。
  
 FIELDWIDTHS     在对记录进行固定域宽的分割时,可以替代FS的分隔符的列表。

  
 FILENAME          当前的输入文件名。

  
 FNR                   当前文件的记录号。

  
 FS                     输入分隔符,默认是空格。

  
 IGNORECASE      在正则表达式和字符串操作中关闭大小写敏感。

  
 NF                     当前文件域的数量。

  
 NR                     当前文件记录数。

  
 OFMT                 数字输出格式。

  
 OFS                   输出域分隔符。

  
 ORS                   输出记录分隔符。

  
 RLENGTH           通过match函数匹配的字符串的长度。

  
 RS                     输入记录分隔符。

  
 RSTART             通过match函数匹配的字符串的偏移量。

  
 SUBSEP             下标分隔符。


  
 /> cat employees2

    Tom Jones:4424:5/12/66:543354
    Mary Adams:5346:11/4/63:28765
    Sally Chang:1654:7/22/54:650000
    Mary Black:1683:9/23/44:336500
    
    />
awk -F: '{IGNORECASE = 1}; $1 == "mary adams" { print NR, $1, $2, $NF}' employees2

    2 Mary Adams 5346 28765
    />
awk -F: ' $1 == "mary adams" { print NR, $1, $2, $NF}' employees2

    没有输出结果。
    当IGNORECASE内置变量的值为非0时,表示在进行字符串操作和处理正则表达式时关闭大小写敏感。这里的"mary adams"将匹配文件中的"Mary Admams"记录。最后print打印出第一、第二和最后一个域。需要说明的是NF表示当前记录域的数量,因此$NF将表示最后一个域的值。
    
    awk在动作部分还提供了BEGIN块和END块。其中BEGIN动作块在awk处理任何输入文件行之前执行。事实上,BEGIN块可以在没有任何输入 文件的条件下测试。因为在BEGIN块执行完毕以前awk将不读取任何输入文件。BEGIN块通常被用来改变内建变量的值,如OFS、RS或FS等。也可
以用于初始化自定义变量值,或打印输出标题。

    />
awk 'BEGIN {FS = ":"; OFS = "\t"; ORS = "\n\n"} { print $1,$2,$3} filename

    上例中awk在处理文件之前,已经将域分隔符(FS)设置为冒号,输出文件域分隔符(OFS)设置为制表符,输出记录分隔符(ORS)被设置为两个换行符。BEGIN之后的动作模块中如果有多个语句,他们之间用分号分隔。
    和BEGIN恰恰相反,END模块中的动作是在整个文件处理完毕之后被执行的。
    />
awk 'END {print "The number of the records is " NR }' filename

    awk在处理输入文件之后,执行END模块中的动作,上例中NR的值是读入的最后一个记录的记录号。
    
    />
awk '/Mary/{count++} END{print "Mary was found " count " times." }' employees2

    Mary was found 2 times.

    />
awk '/Mary/{count++} END{print "Mary was found " count " times." }' employees2


    Mary was found 2 times.

    

    />
cat testfile


    northwest       NW      Charles Main                3.0     .98     3       34

    western          WE      Sharon Gray                5.3     .97     5       23

    southwest       SW      Lewis Dalsass              2.7     .8      2       18

    southern         SO      Suan Chin                   5.1     .95     4       15

    southeast        SE      Patricia Hemenway        4.0     .7      4       17

    eastern           EA      TB Savage                   4.4     .84     5       20

    northeast        NE      AM Main Jr.                  5.1     .94     3       13

    north             NO       Margot Weber             4.5     .89     5       9

    central           CT       Ann Stephens              5.7     .94     5       13


    />
awk '/^north/{count += 1; print count}' testfile
     #如记录以正则north开头,则创建变量count同时增一,再输出其值。

    1

    2

    3

    

    #这里只是输出前三个字段,其中第七个域先被赋值给变量x,在自减一,最后再同时打印出他们。

    />
awk 'NR <= 3 {x = $7--; print "x = " x ", $7 = " $7}' testfile


    x = 3, $7 = 2

    x = 5, $7 = 4

    x = 2, $7 = 1    

    

    #打印NR(记录号)的值在2--5之间的记录。

    />
awk 'NR == 2,NR == 5 {print "The record number is " NR}' testfile


    The record number is 2

    The record number is 3

    The record number is 4

    The record number is 5


    #打印环境变量USER和HOME的值。环境变量的值由父进程shell传递给awk程序的。

    />
awk 'BEGIN { print ENVIRON["USER"],ENVIRON["HOME"]}'


    root /root

    

    #BEGIN块儿中对OFS内置变量重新赋值了,因此后面的输出域分隔符改为了\t。

    />
awk 'BEGIN { OFS = "\t"}; /^Sharon/{ print $1,$2,$7}' testfile


    western WE      5

    

    #从输入文件中找到以north开头的记录count就加一,最后在END块中输出该变量。

    />
awk '/^north/{count++}; END{print count}' testfile


    3

   2.  
 重新定向:


    在动作语句中使用shell通用的重定向输出符号">"就可以完成awk的重定向操作,当使用>的时候,原有文件将被清空,同时文件 持续打开,直到文件被明确的关闭或者awk程序终止。来自后面的打印语句的输出会追加到前面内容的后面。符号">>"用来打开一个文件但是不 清空原有文件的内容,重定向的输出只是被追加到这个文件的末尾。

    />
awk '$4 >= 70 {print $1,$2 > "passing_file"}' filename 
 #注意这里的文件名需要用双引号括起来。

    #通过两次cat的结果可以看出>和>>的区别。

    />
awk '/north/{print $1,$3,$4 > "districts" }' testfile

  
 /> cat districts


    northwest Joel Craig

    northeast TJ Nichols

    north Val Shultz

  
 /> awk '/south/{print $1,$3,$4 >> "districts" }' testfile

  
 /> cat districts


    northwest Joel Craig

    northeast TJ Nichols

    north Val Shultz

抱歉!评论已关闭.