zoukankan      html  css  js  c++  java
  • shell用法总结

    shell基础的一些东西


      ●umask   --查看当前用户创建文件或文件夹时的默认权限
     

    [test@szbirdora 1]$umask
    0002
    [test@szbirdora 1]$ls -lh
    -rw-rw-r--     test test   myfile    
    drwxrwxr-x     test test   1

    上面的例子中我们看到由test默认创建的文件myfile和文件夹1的权限分别为664,775.而通过umask查到的默认权限为002.所以可以推断出umask的计算算法为:
    umask                  file                      directory
    0                           6                            7
    1                           5                            6
    2                           4                            5
    3                           3                            4
    4                           2                            3
    5            1          2
    6            0               1 
    7            0               0
     总结:

    规律:如果文件权限位=7-umask-1  目录权限位=7-umask


    ●连接ln
    硬连接 ln sourcefile targetfile                  连接后的target文件大小和source文件一样,如果删除文件,必须硬链接数为0时,才表示真正的删除
    软连接 ln -s sourcefile targetfile              类似于windows的快捷方式
     
    ●shell script 基本结构
    #!/bin/bash                          --------bash shell开头必须部分
    # description                          --------注释部分(可有可无,为了阅读方便最好加以说明)
    variable name=value             ---------变量部分,声明变量,赋值
    control segment                    ---------流程控制结构,如判断、循环、顺序

    #创建helloworld.sh
    #! /bin/bash
    # This is a helloworld shell script
    printchar = "hello world"
    echo $printchar

    [test@szbirdora 1]$sh helloworld.sh
      hello world
     
    ●shell 特性
    ①别名          alias                  eg. alias ll = “ls -l”
    ②管道          a |b                   将a命令的输出作为b命令的输入 eg. ls |sort   将ls列举的项排序
    ③命令替换   a `b`                 将b命令的输出作为a命令的输入 eg.   ls `cat myfile` 列举出cat myfile的输出项
    ④后台运行   nohup command&    可通过jobs -l查看后台运行的脚本,输出信息重定向到nohup.out,以追加的形式
    ⑤重定向       >,<                      可以改变程序运行的输出来源和输入来源
    ⑥变量                                       可以用$varname 来调用变量
    ⑦特殊字符
                         `用来替换命令
                        用来使shell无法认出其后的特殊字符,使其失去特殊含义
                        ;允许一行放多个命令
                        () 创建成组的命令  
                        {} 创建命令块          
     
    关于变量和运算符:
     
      ●本地变量:在用户现在的shell生命期的脚本中使用。设置变量:various_name=value.可用set 来查看。用readonly可以使变量只读。
      ●环境变量:用于当前用户下所有用户进程(不限于现在的shell)。
                          设置变量:export various_name=value。用env查看。
                          用readonly可以使变量只读。
    ●变量替换   
      echo ${variablename}                   显示实际值到variablename
      echo ${variablename:+value}     如果设置了variablename,则显示value值,否则为空
      echo ${variable name:?value}     如果未设置variablename,则显现用户定义错误信息value
      echo ${variablename:-value}      如果未设置variablename,则显示value,否则显示variablename
      echo ${variablename:=value}        如果未设置,则设置其值,并显示,若已经设置,则只是显示
    ●清除变量                                    unset variable name
    ●位置变量
    位置变量表示$0,$1,$2...$9
      $0 ----脚本名字
      $1 ----根据参数位置表示参数1

    #! /bin/bash
    #parm.sh
    echo "This is script name : $0"
    echo "This is parameter 1: $1"
    echo "This is parameter 2: $2"

    [test@szbirdora 1]$sh parm.sh a b
      This is script name : parm.sh
      This is parameter 1: a
      This is parameter 2: b
    ●向系统中传递位置变量

    #!/bin/bash
    #parm.sh
    find /u01/test/1 -name $1 -print

    [test@szbirdora 1]$ sh parm.sh myfile
    /u01/test/1/myfile


    ●标准变量                              bash默认建立了一些标准环境变量,可在/etc/profile中定义
    EXINIT
    HOME
    IFS
    LOGNAME                                       --当前登录用户名
    MAIL
    MAILPATH
    PATH
    TERM                                              --终端信息
    TZ                                                  --时区
    PS1                                                --登录提示,如[test@szbirdora 1]$

    [test@szbirdora 1]$ echo $PS1
    [u@h w]$                                    --u -user --h -host --w -path


    PS2                                                --一命令多行,换行提示 二级提示符,一行命令没有全部输出,换行后的提示符,,如>
    PWD                                                --当前目录
    MAILCHECK                                   --每隔多少秒检查是否有新邮件

    [test@szbirdora 1]$ echo $MAILCHECK
    60


    SHELL                                            --当前shell
    MANPATH                                       --帮助文档位置
    TERMINFO                                     --终端信息


    ●特殊变量
    $#          传递到脚本的参数个数
    $*          以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
    $$          脚本运行的当前进程ID号
    $!          后台运行的最后一个进程的进程ID号
    $@         传递到脚本的参数列表,并在引号中返回每个参数,与$*类似
    $-          显示shell使用的当前选项,与set命令功能相同
    $?         显示最后命令的退出状态,0表示没有错误,其他表示有错误
    eg.

    #!/bin/bash
    #parm
    echo "this is shellname: $0"
    echo "this is parm1 :    $1"
    echo "this is parm2 :    $2"
    echo "show parm number : $#"
    echo "show parm list :   $*"
    echo "show process id:   $$"
    echo "show precomm stat: $?"

    [test@szbirdora 1]$ sh parm.sh a b
    this is shellname: parm.sh
    this is parm1 :    a
    this is parm2 :    b
    show parm number : 2
    show parm list :   a b
    show process id:   24544
    show precomm stat: 0


    ●影响变量的命令
    declare 设置或显示变量
          -f     只显示函数名
           -r    创建只读变量
          -x     创建转出变量
           -i    创建整数变量
          使用+替代-,可以颠倒选项的含义,比如调试时用的比较多的set -x开启调试信息,set +x 关闭调试信息

    export
          -p   显示全部全局变量


    shift[n]    移动位置变量,调整位置变量,使$3赋予$2,使$2赋予$1     n 前移n,比如shift 1 ,就是原来属于$1的变成$2,$2的变成$3

    typeset     和declare同义
     
    注意:双引号不能解析$,\,`三个字符,所以在双引号中可以引用变量、转义字符、替换变量

    比如  echo -e "$var   `ls -l`"  如果需要echo支持转义字符需要加-e选项


    单引号可以解析,所以单引号中引用变量等无效
    [test@szbirdora 1]$ echo "$test"
    test
    [test@szbirdora 1]$ echo '$test'
    $test


    ●运算符类型
    ⒈按位运算符
    ~    取反
    <<   左移运算符
    >>   右移运算符
    &    与
    |     或
    ^     异或
    $[ ]    表示形式告诉shell对方括号中表达式求值 $[a+b]


    2.逻辑运算符
    &&
    ||
    >,<,=,!=

    3.赋值运算符
    let variablename1=variablename1+ varablename2
    let variablename1 +=variablename1

    关于 shell的输入和输出
    1.echo    echo [option] string
                -e 解析转移字符
               -n 回车不换行,linux系统默认回车换行
                转移字符 c f

    #!/bin/bash
    #echo
    echo -e "this echo's 3 newlne
    
    
    "
    echo "OK"
    echo
    echo "this is echo's 3 ewline
    
    
    "
    echo "this log file have all been done">mylogfile.txt

    [test@szbirdora ~]$ sh echod.sh
    this echo's 3 newlne
     
    OK

    this is echo's 3 ewline
    上面可以看到有-e则可以解析转移字符,没有不能解析。echo空输出为空


    2.read 可以从键盘或文件的某一行文本中读入信息,并将其赋给一个变量
    read variable1 variable2
    eg.

    #!/bin/bash
    #readname
    echo -n "first name:"
    read firstname
    echo -n "last name:"
    read lastname
    echo "this name is $firstname $lastname"
     

    3.cat        显示文件的内容,创建内容,还可以显示控制字符
                cat [options]filename1 filename2
                       -v   显示控制字符(Windows文件)
                 cat命令不会分页显示,要分页可以采用more、less


    4.管道|


    5.tee     把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中,一般与管道合用
                  tee [options] files
                  -a 在文件中追加
    eg.
    [test@szbirdora 1]$ echo |tee myfile
    [test@szbirdora 1]$ cat myfile
     
    将myfile文件置空


    6.文件重定向
    command>filename                                        ---覆盖输出 
    command>>filename                                      ---追加输出
    command>filename 2>&1                                 ---把标准输出和标准错误重定向
    command<<delimiter                                     ---输入直到delimiter分解符
    command<filename                                       ----输入文件内容到命令
    command<-                                                     --- 关闭标准输入
    >nullfile.txt                                                       ---创建字节为0的文件
    command1<filename>command3               ---按从左到右顺序执行
    eg.
    说明:myfile为空间
    [test@szbirdora 1]$ df -lh>myfile
    [test@szbirdora 1]$ cat myfile
    Filesystem            Size Used Avail Use% Mounted on
    /dev/sda1              20G  3.3G  16G    18%     /
    none                   2.0G   0       2.0G   0%     /dev/shm
    /dev/sda2              79G   17G   59G    23%   /u01
    /dev/sda4              28G 3.9G   22G   15%     /u02

    [test@szbirdora 1]$ cat >>myfile<<exit
    > China
    > Hubei
    > Suizhou
    > exit

    从标准输入读到exit为止,并追加输入到myfile
    [test@szbirdora 1]$ cat myfile
    China
    Hubei
    Suizhou


    7.exec        可以用来替代当前shell。现有任何环境变量都会清除


    第四章 控制流结构
    1.if语句
    if 条件1
    then 
         命令1
    elif 条件2
    then 
         命令2
    else
         命令3
    fi
    ------------------
    if 条件
    then 命令
    fi
    eg:

    #!/bin/bash
    #if test
    #this is a comment line
    if [ "10" -lt "12" ];then
    #yes 10 is less than 12
    echo "yes,10 is less than 12"
    else
    echo "no"
    fi

    注意:if语句必须以fi终止
       "10" 前一个空格,“12”后也有一个空格。这个条件都是通过test命令来指定。条件表达为test expression或者[expression]
     
    条件表达式中的比较函数
    man test

    NAME
           test - check file types and compare values
    SYNOPSIS
           test EXPRESSION
           [ EXPRESSION ]
           [ OPTION
    DESCRIPTION
           Exit with the status determined by EXPRESSION.
           --help display this help and exit
           --version
                  output version information and exit
           EXPRESSION is true or false and sets exit status. It is one of:
           ( EXPRESSION )
                  EXPRESSION is true
           ! EXPRESSION
                  EXPRESSION is false
           EXPRESSION1 -a EXPRESSION2
                  both EXPRESSION1 and EXPRESSION2 are true
           EXPRESSION1 -o EXPRESSION2
                  either EXPRESSION1 or EXPRESSION2 is true
           [-n] STRING
                  the length of STRING is nonzero
           -z STRING
                  the length of STRING is zero
           STRING1 = STRING2
                  the strings are equal
           STRING1 != STRING2
                   the strings are not equal
           INTEGER1 -eq INTEGER2
                  INTEGER1 is equal to INTEGER2
           INTEGER1 -ge INTEGER2
                  INTEGER1 is greater than or equal to INTEGER2
           INTEGER1 -gt INTEGER2
                  INTEGER1 is greater than INTEGER2
           INTEGER1 -le INTEGER2
                  INTEGER1 is less than or equal to INTEGER2
           INTEGER1 -lt INTEGER2
                  INTEGER1 is less than INTEGER2
           INTEGER1 -ne INTEGER2
                  INTEGER1 is not equal to INTEGER2
           FILE1 -ef FILE2
                  FILE1 and FILE2 have the same device and inode numbers
           FILE1 -nt FILE2
                  FILE1 is newer (modification date) than FILE2
           FILE1 -ot FILE2
                  FILE1 is older than FILE2
           -b FILE
                  FILE exists and is block special
           -c FILE
                  FILE exists and is character special
           -d FILE
                  FILE exists and is a directory
           -e FILE
                  FILE exists
           -f FILE
                  FILE exists and is a regular file
           -g FILE
                  FILE exists and is set-group-ID
           -h FILE
                  FILE exists and is a symbolic link (same as -L)
           -G FILE
                  FILE exists and is owned by the effective group ID
           -k FILE
                  FILE exists and has its sticky bit set
           -L FILE
                  FILE exists and is a symbolic link (same as -h)
           -O FILE
                  FILE exists and is owned by the effective user ID
           -p FILE
                  FILE exists and is a named pipe
           -r FILE
                  FILE exists and is readable
           -s FILE
                  FILE exists and has a size greater than zero
           -S FILE
                  FILE exists and is a socket
           -t [FD]
                  file descriptor FD (stdout by default) is opened on a terminal
           -u FILE
                  FILE exists and its set-user-ID bit is set
           -w FILE
                  FILE exists and is writable
           -x FILE
                 FILE exists and is executable


    eg.

    #!/bin/bash
    #if test
    #this is a comment line
    echo "Enter your filename:"
    read myfile
    if [ -e $myfile ]
    then
       if [ -s $myfile ];then
        echo "$myfile exist and size greater than zero"
       else
        echo "$myfile exist but size is zero"
       fi
    else
    echo "file no exist"
    fi


    [test@szbirdora 1]$ sh iftest.sh 
    Enter your filename:
    11
    11 exist but size is zero


    2.case语句
    case语句为多选择语句。
    case 值 in
    模式1)
        命令1
        ;;
    模式2)
        命令2
        ;;
    esac

    eg.

    #!/bin/bash
    #case select
    echo -n "enter a number from 1 to 3:"
    read ans
    case $ans in
    1)
    echo "you select 1"
    ;;
    2)
    echo "you select 2"
    ;;
    3)
    echo "you select 3"
    ;;
    *)
    echo "`basename $0`:this is not between 1 and 3">&2
    exit;
    ;;
    esac


    3.for 循环
    for循环一般格式:
    for 变量名 in 列表 (列表以空格作为分割)
    do
       命令1
       命令2
    done
    eg:

    #!/bin/bash
    #forlist1
    for loop in 1 2 3 4 5
    do
    echo $loop
    done


    4.until循环
    until 条件
    do
       命令1
       命令2
       ...
    done
    条件测试发生在循环末尾,所以循环至少可以执行一次。直到条件满足


    5.
    while循环
    while 命令 (可以是一个命令也可以是多个,做条件测试)或者测试条件
    do
          命令1
          命令2
          ...
    done

    从文件中按照行读数据
    
    #!/bin/bash
    #while02
    while read LINE 
    do
            echo $LINE
    done < names.txt 


    注意:如果从文件中读入变量<filename要放到done后

    #!/bin/bash
    #while02
    #这样写是不对的 ,需要把<name.txt 放在 while循环后面
    while read LINE < names.txt   
    do
            echo $LINE
    done  

    6.break和continue控制
      break跳出,continue跳过
     
    第五章 文本过滤
     
    1.正则表达式
    一种用来描述文本模式的特殊语法,由普通字符以及特殊字符(元字符)组成
    ^    ----只匹配行首
    $    ----只匹配行尾
    *    ----匹配0个或多个此单字符
    []   ----只匹配[]内字符,可以使用-表示序列范围[1-5]
       ----屏蔽一个元字符的特殊含义
    .    ----匹配任意单字符
    pattern{n} 只用来匹配前面pattern出现的次数,n为次数
    pattern{n,}只用来匹配前面pattern出现的次数,至少为n
    pattern{n,m}只用来匹配前面pattern出现的次数,次数在n-m之间
    eg:

    A{3}B   AAAB
    A{3,}B  AAAB AAAAB ...
    A{3,5}B AAAB AAAAB AAAAAB


    2.find命令     ----查找文件和目录
      find pathname -options [-print -exec -ok]
    pathname --查找的目录路径.    '. '--表示当前目录,/表示根目录
    -print 输出
    -exec 对匹配的文件执行该参数所给出的shell命令,相应命令形式为'command'{} ;'    注意{}和;之间的空格 如  :find ./ -name "*.sh" -exec ls -l {} ;


    -ok    与-exec相同,不过执行命令前会有提示 
    options   : 
    -name 
    -perm 
    -user 
    -group 
    -mtime -n +n (atime,-ctime) 修改时间(访问时间,创建时间)+n超过n天,-n为n天以内

    -size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
    -depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。默认就支持

    -type 查找某一类型的文件
    eg.
    [test@szbirdora 1]$ find ./ -mtime +5
    ./helloworld.sh
    ./nohup.out
    查看./目录(当前)下修改时间超过5天的文件
     
    3.grep介绍
    grep -c 输出匹配行计数
    grep -i 不区分大小写
    grep -h 查询多文件时不显示文件名
    grep -H 显示文件名
    grep -l 查询多文件时只输出包含匹配字符的文件名
    grep -n 显示匹配行及行号
    grep -s 不显示不存在或不匹配文本的错误信息
    grep -v 显示不包含匹配文本的所有行(过滤文本)
     
    eg.
    [test@szbirdora 1]$ grep -n 's.a' myfile
    2:/dev/sda1              20G 3.3G   16G 18% /
    4:/dev/sda2              79G   18G   58G 23% /u01
    5:/dev/sda4              28G 3.9G   22G 15% /u02
    [test@szbirdora 1]$ grep -n '2$' myfile
    5:/dev/sda4              28G 3.9G   22G 15% /u02


    grep -options '正则表达式' filename
     
    4.sed介绍
    sed不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件将输出到屏幕
    sed是一种重要的文本过滤工具,使用一行命令或使用管道与grep与awk相结合。
    sed调用:
     1.命令  sed [options] '正则表达式sedcommand' input-files
    2.script : sed [options] -f sedscript input-files
    sed在文本中查询文本的方式
       -行号,可以是简单数字,或一个行号范围
       -使用正则表达式
     x ----行号
       x,y ----行号范围从x到y
       x,y! ---不包含行号x到y
    sed 选项含义

     --version            显示sed版本。

        --help               显示帮助文档。

        -n,--quiet,--silent    静默输出,默认情况下,sed程序在所有的脚本指令执行完毕后,将自动打印模式空间中的内容,这些选项可以屏蔽自动打印。

        -e script              允许多个脚本指令被执行。

        -f script-file,

        --file=script-file        从文件中读取脚本指令,对编写自动脚本程序来说很棒!

        -i,--in-place        直接修改源文件,经过脚本指令处理后的内容将被输出至源文件(源文件被修改)慎用!

         -l N, --line-length=N    该选项指定l指令可以输出的行长度,l指令用于输出非打印字符。

         --posix            禁用GNU sed扩展功能。

         -r, --regexp-extended   在脚本指令中使用扩展正则表达式

         -s, --separate        默认情况下,sed将把命令行指定的多个文件名作为一个长的连续的输入流。GNU sed则允许把他们当作单独的文件, 这样如正则表达式则不进行跨文件匹配。

         -u, --unbuffered      最低限度的缓存输入与输出。

    基本sed命令
    p   打印匹配行
    =   显示文本行号
    a     在定位行号后附加新文本信息
    i    在定位行号前插入新文本信息
    d       删除定位行
    c  用新文本替换定位文本
    s   使用替换模式替换相应模式
    r   从另一个文件中读文本
    w   写文本到一个文件
    q   第一个模式匹配完成后退去
    l   显示与八进制ascii代码等价的控制字符
    {}  在定位行执行命令组
    n   从一个文件中读文本下一行,并附加在下一行
    g   将模式2粘贴到/pattern n/
    y   传送字符

    这里就简单介绍几个脚本指令操作作为sed程序的例子。

        a,append        追加

        i,insert        插入

        d,delete        删除

        s,substitution  替换

    sed基本语法结构

    sed  Options...  [script]   [inputfile...]
    sed  选项...       [脚本指令]      [输入文件]
    如果没有输入文件,则sed默认对标准输入进行处理(即键盘输入)。脚本指令是第一个不以“-”开始的参数。

    1.选项含义:

       

    查找替换应用举例
    sed  '2a TYPE=Ethernet'  test.txt    第二行后添加TYPE=Ethernet
    sed  '3i  TYPE=Ethernet'  test.txt   第三行前添加TYPE=Ethernet
    sed  's/yes/no/g'     test.txt       将样本文件中的所有yes替换为no
    sed  '3,4d'  test.txt                删除第3至4行的内容
    总结:以上大多数操作指令,都依据行号定位操作对象(地址),如:2a即第二行后添加。
    但实际情况可能大多数情况你并不确定你要操作对象(地址)的行号,这时更多的我们会使用正则表达式确定操作对象(地址)。
    

      

    下面是使用正则表达式定位操作行的示例:
    sed  '/222/a iiii=1111 '  testfile.txt
    匹配到包含222的行,并在其后添加iiii=1111
    sed  '/^aaa/d'  testfile.txt
    匹配以aaaa开始的行,并删除改行
    需要执行多个指令时,可以使用以下三种方法:
    #sed  's/yes/no/;s/static/dhcp/'  test.txt            注:使用分号隔开指令。
    
    #sed 
    -e  's/yes/no/'    -e  's/static/dhcp/'  test.txt    注:使用-e选项。 #sed '     >s/yes/no/     >s/static/dhcp/'  test.txt                                    注:利用分行指令。  然而在命令行上输入过长的指令是愚蠢的,这时就需要-f选项指定sed脚本文件,在脚本文件中可以包含多行指令,而且便于修改!
    sed  -i  's/^M//g'  a.txt > new.out  (-i选项是会直接修改源文件的,慎用)
    cat gpdata_wbm10.bak | sed 's/^M//g' | awk '$0' > 2.log


    eg.
    [test@szbirdora 1]$ sed -n '2p' myfile
    c
    打印myfile第2行
    [test@szbirdora 1]$ sed -n '2,4p' myfile
    c
    f
    b
    打印第二行到第四行
    [test@szbirdora 1]$ sed -n '/a/p' myfile
    a
    打印匹配a的行
    [test@szbirdora 1]$ sed -n '2,/2/p' myfile
    c
    f
    b
    1
    2
    打印第二行到匹配'2'的行
     
     
     
     
    s命令替换
    [test@szbirdora 1]$ sed 's/b/a/p' myfile
    a
    a
    a
    c
    d
    e
    替换b为a
     
    允许多个脚本指令被执行。-e
    eg. (myfile包含a-e)
    [test@szbirdora 1]$ sed -e '2d' -e 's/c/d/' myfile 11
    a
    d
    d
    e
     删除第二行并且把c替换成d
    sed命令r ---从文件中读取选定的行,读入输入文件中,显示在匹配的行后面
    eg.
    [test@szbirdora 1]$ cat 11
    *******************Alaska***************
    [test@szbirdora 1]$ sed '/a/r 11' myfile
    a
    *******************Alaska***************
    b
    c
    d
    e
     从myfile中匹配a的行并把文件11的内容放到a的后面并输出到标准输出


    写入命令:w   将输入文件中的匹配行写入到指定文件中
    eg.
    [test@szbirdora 1]$ cat 11
    b
    [test@szbirdora 1]$ sed -n '/a/w 11' myfile
    [test@szbirdora 1]$ cat 11
    a
     就是把myfile中匹配到的a写入到11文件中,原来文件11的内容会被清空


    追加:a   将文本追加到匹配行的后面。sed要求在a后加\,不止一行的以连接
    eg.
    [test@szbirdora 1]$ sed '/b/a****************hello*************-------------china---------' myfile
    a
    b
    ****************hello*************-------------china---------
    c
    d
    e

    在b的后面追加但不写入文件
     
    插入命令:i   将文本插入到匹配行的前面。sed要求在a后加\,不止一行的以连接
    eg.
    [test@szbirdora 1]$ sed '/b/i
    > THE CHARACTER B IS BEST
    > *******************************' myfile

    a
    THE CHARACTER B IS BEST
    *******************************
    b
    c
    d
    e
    插入到b前面,不修改文件

     
    下一个:n 从一个文件中读文本下一行,并附加在下一行
     
    退出命令 q 打印多少行后退出
    eg.
    [test@szbirdora 1]$ sed '3q' myfile
    a alert
    b best
    c cook
     
    sed script:用法
    sed -f scriptfile myfile
     
    5.awk介绍

    awk可从文件或字符串值基于指定规则浏览和抽取信息
    awk三种调用方式:
    1.命令行方式
    awk [-F field-sperator]'pattern{active}' input-files
    awk [-F field-sperator]'command' input-files
    awk脚本
    所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解析器作为脚本的首行,以便通过键入脚本名称来调用。
    awk命令插入一个单独文件
    awk -f awk-script-file input-files
     
     
    awk脚本由模式和动作组成
    分隔符、域、记录
    注意这里的$1,$2是域与位置变量$1,$2不一样。$0文件中的所有记录
    eg:
    awk '{print $0}' myfile
    awk 'BEGIN {print "IP DATE ----"}{print $1" "$4}END{print "end-of -report"}
    [test@szbirdora 1]$ df |awk '$1!~"dev"'|grep -v Filesystem
    none                   1992400         0   1992400   0% /dev/shm
    [test@szbirdora 1]$ df |awk '{if ($1=="/dev/sda1") print $0}'
    /dev/sda1             20641788   3367972 16225176 18% /
     
    [test@szbirdora shelltest]$ cat employee
    Tom Jones       4424    5/12/66 543354
    Mary Adams      5346    11/4/63 28765
    Sally Chang     1654    7/22/54 650000
    Billy Black     1683    9/23/44 336500
    [test@szbirdora shelltest]$ awk '/[Aa]dams/' employee 
    Mary Adams      5346    11/4/63 28765
    [test@szbirdora shelltest]$ sed -n '/[Aa]dams/p' employee
    Mary Adams      5346    11/4/63 28765
    [test@szbirdora shelltest]$ grep '[Aa]dams' employee
    Mary Adams      5346    11/4/63 28765
    三种命令方式下,使用模式匹配查询
     
    [test@szbirdora shelltest]$ awk '{print $1}' employee
    Tom
    Mary
    Sally
    Billy
    打印文件第一列
     
    [test@szbirdora shelltest]$ awk '/Sally/{print $1" "$2}' employee
    Sally   Chang
      打印匹配Sally的行的第一列和第二列
     
    [test@szbirdora shelltest]$ df |awk '$4>20884623'
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda2             82567220  17488436 60884616 23% /u01
    /dev/sda4             28494620   4589172 22457992 17% /u02
    打印df输出第四列大于××的行
     
    格式输出:
    打印函数—
    [test@szbirdora shelltest]$ date
    Mon Mar 10 15:15:47 CST 2008
    [test@szbirdora shelltest]$ date |awk '{print "Month:" $2" Year:" $6}'
    Month:Mar
    Year:2008
    [test@szbirdora shelltest]$ awk '/Sally/{print " Have a nice day,"$1" "$2}' employee 
                    Have a nice day,Sally   Chang
     
    printf函数
    [test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%-10s| ",$1}'
    |LINUX     |
    [test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%10s| ",$1}'
    |     LINUX|
     
    ~匹配符
    [test@szbirdora shelltest]$ awk '$1~/Tom/{print $1,$2}' employee 
    Tom Jones
     也可以这样写 awk '{if($1~"Tom") print $1,$2}'

    可见awk用法比较灵活


    awk 给表达式赋值
    关系运算符:
    <             小于   
    >             大于
    ==           等于
    !=            不等于
    >=           大于等于
    <=           小于等于
    ~              匹配
    !~            不匹配
    eg.
    [test@szbirdora shelltest]$ cat employee 
    Tom Jones       4424    5/12/66 543354
    Mary Adams      5346    11/4/63 28765
    Sally Chang     1654    7/22/54 650000
    Billy Black     1683    9/23/44 336500
    [test@szbirdora shelltest]$ awk '$2~/Adams/' employee 
    Mary Adams      5346    11/4/63 28765
     
    条件表达式:
    condition   expression1?expression2:expression3
    eg.
    awk '{max=($1>$2) ? $1:$2;print max}' filename
     
    运算符
    +,-,*,/,%,^,&&,||,!
     
    [test@szbirdora shelltest]$ cat /etc/passwd |awk -F: '
    NF!=7{
    printf("line %d does not have 7 fields:%s ",NR,$0)}
    $1!~/[A-Za-z0-9]/{printf("line %d,nonalphanumberic user id:%s ",NR,$0)}
    $2=="*"{printf("line %d,no password:%s ",NR,$0)}'
    NF 就是字段数,NR就是已经读取的记录数

    具体可以查看这个博客

    https://blog.csdn.net/qq_34685846/article/details/73224709 


    awk编程
    递增操作符 x++,++x
    递减操作符 x--,--x
     
    BEGIN模块
    BEGIN模块后面紧跟着动作块,在读入文件前执行。通常被用来改变内建变量的值,如:FSRSOFS,初始化变量的值和打印输出标题。
    [test@szbirdora shelltest]$ awk 'BEGIN{print "HELLO WORLD"}'
    HELLO WORLD
    [test@szbirdora shelltest]$ awk 'BEGIN{print "---------LIST---------"}{print}END{print "------END--------"}' donors 
    ---------LIST---------
    Mike Harrington:(510) 548-1278:250:100:175
    Christian Dobbins:(408) 538-2358:155:90:201
    Susan Dalsass:(206) 654-6279:250:60:50 
    Archie McNichol:(206) 548-1348:250:100:175 
    Jody Savage:(206) 548-1278:15:188:150 
    Guy Quigley:(916) 343-6410:250:100:175 
    Dan Savage:(406) 298-7744:450:300:275 
    Nancy McNeil:(206) 548-1278:250:80:75 
    John Goldenrod:(916) 348-4278:250:100:175 
    Chet Main:(510) 548-5258:50:95:135 
    Tom Savage:(408) 926-3456:250:168:200 
    Elizabeth Stachelin:(916) 440-1763:175:75:300
    ------END--------
     
    重定向和管道
    输出重定向
    awk输出重定向到一个文件需要使用输出重定向符,输出文件名需要用双引号括起来。
    [test@szbirdora shelltest]$ awk -F: '{print $1,$2>"note"}' donors 
    [test@szbirdora shelltest]$ cat note
    Mike Harrington (510) 548-1278
    Christian Dobbins (408) 538-2358
    Susan Dalsass (206) 654-6279
    Archie McNichol (206) 548-1348
    Jody Savage (206) 548-1278
    Guy Quigley (916) 343-6410
    Dan Savage (406) 298-7744
    Nancy McNeil (206) 548-1278
    John Goldenrod (916) 348-4278
    Chet Main (510) 548-5258
    Tom Savage (408) 926-3456
    Elizabeth Stachelin (916) 440-1763
     
    输入重定向
    getline函数
    [test@szbirdora shelltest]$ awk 'BEGIN{"date +%Y"|getline d;print d}'
    2008
     
    [test@szbirdora shelltest]$ awk -F"[ :]" 'BEGIN{printf "What is your name?";
    getline name<"/dev/tty"}
    $1~ name{print "Found " name " on line",NR"."}
    END{print "see ya," name "."}' donors
    What is your name?Jody
    Found   Jody    on line 5.
    see ya,Jody.
     
    [test@szbirdora shelltest]$ awk 'BEGIN{while(getline<"/etc/passwd">0)lc++;print lc}'
    36
    从文件中输入,如果得到一个记录,getline函数就返回1,如果文件已经到了末尾,则返回0,如果文件名错误则返回-1.
     
    管道:
    awk命令打开一个管道后要打开下一个管道需要关闭前一个管道,管道符右边可以使用“”关闭管道。在同一时间只有一个管道存在
    [test@szbirdora shelltest]$ awk '{print $1,$2|"sort -r +1 -2 +0 -1"}' names
    tony tram
    john smith
    dan savage
    john oldenrod
    barbara nguyen
    elizabeth lone
    susan goldberg
    george goldberg
    eliza goldberg
    alice cheba
    |后用""关闭管道
    至于sort请看这个博客:

    http://blog.51cto.com/lspgyy/1282334

     
    system函数
    system("LINUX command")
    system("cat" $1)
    system("clear")
     
    条件语句
    1.if(){}

    2.if(){}
    else{}


    3.if(){}
    else if(){}
    else if(){}
    else{}
    [test@szbirdora shelltest]$ awk -F: '{if ($3>250){printf "%-2s%13s ",$1,"-----------good partman"}else{print $1}}' donors
     
    循环语句
    [test@szbirdora shelltest]$ awk -F: '{i=1;while(i<=NF){print NF,$i;i++}}' donors 
    循环控制语句break、continue
     
    程序控制语句
    next从输入文件中读取下一行,然后从头开始执行awk脚本
    {if($1~/Peter/){next}
    else{print}}
     
    exit 结束awk语句,但不会结束END模块的处理。
     
    数组:
    awk '{name[x++]=$1;for(i=0;i<NR;i++){print i,name[i]}}' donors
     

    awk内建函数
    sub(正则表达式,替换字符[,$n]) ---域n匹配正则表达式的字符串将被替换。
    [test@szbirdora shelltest]$ awk '{sub(/Tom/,"Jack",$1);print}' employee 
    Jack Jones 4424 5/12/66 543354
    Mary Adams      5346    11/4/63 28765
    Sally Chang     1654    7/22/54 650000
    Billy Black     1683    9/23/44 336500
    Jack He 3000 8/22/44 320000
     
    index函数 index(字符串,子字符串) 子字符串在字符串中的位置
    [test@szbirdora shelltest]$ awk 'BEGIN{a=index("hello","llo");print a}'
    3
     
    length函数 length(string) 字符串的长度
    [test@szbirdora shelltest]$ awk 'BEGIN{a=length("hello world");print a}'
    11
     
    substr函数 substr(字符串,开始位置[,子字符串长度])
    [test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7);print a}'
    world
    [test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7,3);print a}'
    wor
     
    match(string,正则表达式) 找出字符串中第一个匹配正则表达式的位置,其内建变量RSTART为匹配开始位置,RLENGTH为匹配开始后字符数
    [test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print NR,a}}' employee 
    1 5
    [test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print NR,a,RSTART,RLENGTH}}' employee 
    1 5 5 3
     
    toupper和tolower函数
    [test@szbirdora shelltest]$ awk 'BEGIN{a=toupper("hello");print a}'
    HELLO
     
    split函数 split(string,array,fieldseperator)
    [test@szbirdora shelltest]$ awk 'BEGIN{"date"|getline d;split(d,date);print date[2]}'
    Mar
     
    时间函数
    systime() ----1970年1月1日到当前忽略闰年得出的秒数。
    strftime(格式描述,时间戳)
    [test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%T",systime());print d}'
    13:08:09
    [test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%D",systime());print d}'
    03/12/08
    [test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%Y",systime());print d}'
    2008
     
    6.sort介绍
    sort:
         -c 测试文件是否已经排序
         -m 合并两个排序文件
         -u 删除所有复制行
         -o 存储sort结果的输出文件名
         -t 域分隔符;用非空格或tab键分割域
         +n n为域号,使用此域号开始排序   (注意0是第一列)
         -r 逆序排序
         n 指定排序是域上的数字排序项
    [test@szbirdora 1]$ df -lh|grep -v 'Filesystem'|sort +1
    none                  2.0G     0 2.0G   0% /dev/shm
    /dev/sda1              20G 3.3G   16G 18% /
    /dev/sda4              28G 3.9G   22G 15% /u02
    /dev/sda2              79G   17G   59G 23% /u01
    uniq [option]files 从一个文本文件中去除或禁止重复行
         -u 只显示不重复行
         -d 只显示有重复数据行,每重复行只显示其中一行
         -c 打印每一重复行出现次数
         -f n为数字,前n个域被忽略
    注意要先排序
    7.split cut join 分割和合并文件命令
    [test@szbirdora 1]$ split -l 2 myfile split   (每两行分割为一个以split名称开头的文件)
    [test@szbirdora 1]$ ls
    case.sh df.out helloworld.sh iftest.sh myfile nohup.out nullfile.txt parm.sh splitaa splitab splitac splitad splitae
    [test@szbirdora 1]$ cat splitaa
    Filesystem            Size Used Avail Use% Mounted on
    /dev/sda1              20G 3.3G   16G 18% /
     即把myfile文件内容每两行分割成以split命名开头的文件
     shell函数
     
    1.定义函数
    funcation name()
    {
       command1
       ....
    }

    函数名()
       {
       command1
       ...
       }
    eg.

    #!/bin/bash
    #hellofun
    function hello()
    {
    echo "hello,today is `date`"
    return 1
    }

    2.函数调用

    #!/bin/bash
    #hellofun
    function hello()
    {
    echo "hello,today is `date`"
    return 1
    }
    echo "now going to the function hello"
    hello
    echo "back from the function"

    所以调用函数只需要在脚本中使用函数名就可以了。

    3.参数传递
    像函数传递参数就像在脚本中使用位置变量$1,$2...$9
    4.函数文件
    函数可以文件保存。在调用时使用". 函数文件名"(.+空格+函数文件名)
    如:

    hellofun.sh
    #!/bin/bash
    #hellofun
    function hello()
    {
    echo "hello,$1 today is `date`"
    return 1
    }
    func.sh
    #!/bin/bash
    #func
    . hellofun.sh
    echo "now going to the function hello"
    echo "Enter yourname:"
    read name
    hello $name
    echo "back from the function"
    [test@szbirdora 1]$ sh func.sh
    now going to the function hello
    Enter yourname:
    hh
    hello,hh today is Thu Mar 6 15:59:38 CST 2008
    back from the function

    5.检查载入函数 set
    删除载入函数 unset 函数名
    6.函数返回状态值 return 0、return 1
    7.脚本参数的传递


    shift命令
    shift n 每次将参数位置向左偏移n

    #!/bin/bash
    #opt2
    usage()
    {
    echo "usage:`basename $0` filename"
    }
    totalline=0
    if [ $# -lt 2 ];then
        usage
    fi
    while [$# -ne 0]
    do
        line=`cat $1|wc -l`
        echo "$1 : ${line}"
        totalline=$[$totalline+$line]
        shift                               #   $# -1
    done
    echo "-----"
    echo "total:${totalline}"

    [test@szbirdora 1]$ sh opt2.sh myfile df.out
    myfile : 10
    df.out : 4
    -----
    total:14
     
    8.getopts命令
    获得多个命令行参数
    getopts ahfvc OPTION   --从ahfvc一个一个读出赋值给OPTION.如果参数带有:则把变量赋值给:前的参数--:只能放在末尾。
    该命令可以做获得命令的参数

    #!/bin/bash
    #optgets
    ALL=false
    HELP=false
    FILE=false
    while getopts ahf OPTION
    do
       case $OPTION in
        a)
          ALL=true
          echo "ALL is $ALL"
          ;;
        h)
          HELP=true
          echo "HELP is $HELP"
          ;; 
        f)
          FILE=true
          echo "FILE is $FILE"
          ;;
        ?)
          echo "`basename $0` -[a h f] file"
          ;;
        esac 
    done
    

      


    [test@szbirdora 1]$ sh optgets.sh -a -h -m
    ALL is true
    HELP is true
    optgets.sh: illegal option -- m
    optgets.sh -[a h f] file
     
    getopts表达式:
    while getopts p1p2p3... var  

     do
        case var in
        ..)
        ....
       esac
    done
    如果在参数后面还需要跟自己的参数,则需要在参数后加:
    如果在参数前面加:表示不想将错误输出
    getopts函数自带两个跟踪参数的变量:optind,optarg

    | Column 1 | Column 2 | Column 3 |
    | -------- | -------- | -------- |
    | Text | Text | Text |


    optind初始值为1,在optgets处理完一次命令行参数后加1
    optarg包含合法参数的值,即带:的参数后跟的参数值

  • 相关阅读:
    MYSQL: 什么是MYSQLD Service
    100 logging模块
    099 hashlib和hmac模块
    098 json和pickle模块
    097 sys模块
    096 os模块
    095 random模块
    094 datetime模块
    093 time模块
    092 模块基础实战之ATM和购物车系统分文件处理
  • 原文地址:https://www.cnblogs.com/bwbfight/p/9402738.html
Copyright © 2011-2022 走看看