zoukankan      html  css  js  c++  java
  • Shell工具| 流程控制

    1. 流程控制

    if 判断

    1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
    (2)if后要有空格
    
    [kris@hadoop datas]$ vim if.sh 
    #!/bin/bash
    if [ $1 -eq "1" ]
    then
            echo "one"
    elif [ $1 -eq "2" ]
    then
            echo "two"
    else
            echo "other"
    fi
    -------------------
    #!/bin/bash
    if [ $1 -eq "1" ]; then echo "one"
    fi

    运算式$[4%2] 和表达式[ 4 -eq 3 ],注意区别

    for循环和if的使用

    
    表达式
    [kris@hadoop datas]$ vi for.sh 
    #!/bin/bash
    
    for ((i=0;i<10;i++))
    do
            if [ $[$i%2] -eq 0 ]
            then
            echo $i
    fi
    done
    
    或者这样写:
    for ((i=0;i<10;i++))
    do
            if [ $(($i%2)) = 0 ]; then echo $i
         fi
    done
    
    [kris@hadoop datas]$ sh for.sh 
    0
    2
    4
    6
    8
    
    #!/bin/bash
    for((i=0;i<10;i++))
    do
            if [ $(($i%2)) = 0 ]; then echo $i
            elif [ $(($i%3)) = 0 ]; then echo $i
            else echo "我是奇数"
    fi
    done

    case

    #!/bin/bash
    case $1 in
    "1")
            echo "Monday"
    ;;
    "2")
            echo "Tuesday"
    ;;
    "3")
            echo "Wednesday"
    ;;
    "4")
            echo "Thursday"
    ;;
    "5")
            echo "Friday"
    ;;
    *)
            echo "Weekend"
    ;;
    esac
    
    [kris@hadoop datas]$ ./case.sh 3
    Wednesday

     while循环

    [kris@hadoop datas]$ vim while.sh 
    #!/bin/bash
    i=1
    s=0
    while [ $i -le 100 ]
    do
      s=$[$s+$i]
      i=$[$i+1]
    done
    echo $s
    [kris@hadoop datas]$ sh while.sh 3333333333
    5050

    read读取控制台输入

    -p:指定读取值时的提示符;
    -t:指定读取值时等待的时间(秒)。
    参数
        变量:指定读取值的变量名
    
    #/bin/bash
    read -p "Please input a num in 5 seconds:" a
    echo $a

    函数function

    bash 可以进入子shell,exit是退出来,
    
    source a.sh是在当前shell执行
    ./a.sh是在子shell中执行的
    
    export 使得当前shell和子shell中定义的变量都起作用

     系统函数

    basename [string / pathname] [suffix] 
    (功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
    suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
    
    [kris@hadoop datas]$ basename /home/kris/datas/while.sh
    while.sh
    [kris@hadoop datas]$ basename /home/kris/datas/while.sh .sh
    while
    
    dirname 文件绝对路径        (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
    [kris@hadoop datas]$ dirname /home/kris/datas/while.sh  
    /home/kris/datas

    自定义函数

    必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
    函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
    
    #/bin/bash
    function sum()
    {
            s=$echo $s
    }
    sum $1 $2
    ~                                                                               
    ~                                                                                                           
    [kris@hadoop datas]$ 
    [kris@hadoop datas]$ sh function.sh 1 3
    4

    2. shell工具

    cut

    cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

    -f (列号,提取第几列)   -d(分隔符,按照指定分隔符分割列)    -c   (指定具体字符,如5--9个字符)

    
    [root@kris datas]# ifconfig | grep Bcast 
              inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
    [root@kris datas]# ifconfig | grep Bcast | cut -c 11-14
    inet
    
    [root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2
    192.168.1.100  Bcast
    [root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 1 
    192.168.1.100
    [root@kris datas]# ifconfig | grep Bcast > temp.log  ##### > 是把原来的内容覆盖、>>是在原内容基础上追加; 
    [root@kris datas]# cat temp.log 
              inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
    [root@kris datas]# cut -d : -f 2 temp.log          
    192.168.1.100  Bcast
    [root@kris datas]# cat temp.log | cut -d : -f 2  #####与上边是的等效的,只是temp.log所放的位置不一样
    192.168.1.100  Bcast
    [root@kris datas]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 3
    Bcast

     sed

    sed按行处理;

    sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出

     -e(直接在指令列模式上进行sed的动作编辑;两个修改指令的方式)  -i (在文件中直接编辑修改文件)   

    a(新增,a的后面可以接字串,在下一行出现 '2axxxx' )  d (删除)

     s(查找并替换 ‘s/Link/xxxx/’ 

    ifconfig | sed '1d'    删除第一行
    
     ifconfig | sed '1,5d' 删除掉前5行
    
     ifconfig | sed '1akris'  在第一行后面(第二行)追加kris
    
    ifconfig | sed 's/Link/XXX/' 查找并替换;注意是区分大小写的,最后的/符号不要忘记了ifconfig | sed 's/Link/XXX/' temp.log  #并不会改变文件内容
    
     ifconfig | sed -i 's/Link/XXX/' temp.log  加上-i就可以在文件中修改成功了;前提是文件中的内容必须是ifconfig输出内容;
    ifconfig | sed  '/^ *R/aXXX'  前边有若干个空格,以R开头的
    
    [root@kris datas]# ifconfig | sed -e '/^ *R/aXXX' -e'/^ *T/d'   
    以R开头的追加XXX
    ,把以T开头的删掉;这是两个式子就不能通过一个式子搞定了,需加-e改变修改方式只有一个时可以省略;

     awk

    一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

    按行处理,可以对行内的数据进行更细微的操作;

    awk [选项参数] ‘pattern1{action1}  pattern2{action2}...’ filename

      pattern:表示AWK在数据中查找的内容,就是匹配模式

      action:在找到匹配内容时所执行的一系列命令

      选项参数:-F(指定输入文件折分隔符)、-v(赋值一个用户定义变量)

    cp /etc/passwd ./
    [root@kris datas]# cat passwd | awk '/^a/{print}' 把以a开头的打印出来 [root@kris datas]# cat passwd | awk '/^a/{print}'   adm:x:3:4:adm:/var/adm:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin [root@kris datas]# cat passwd | awk -F : '/^a/{print $1}' //-F指定输入文件折分隔符   adm   avahi-autoipd   abrt   apache [root@kris datas]# cat passwd | awk -F: '/^a/{print $1} /^adm/{print}' 如果匹配到了以a开头就把print $1打印出来; 如果又匹配到了adm就把print整行打印出;

      adm
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      avahi-autoipd
      abrt
      apache
      alex

    #如果不写模板它就把所有行都打印出
    [root@kris datas]# cat passwd | awk -F : '{print $1}'   ...... [root@kris datas]#
    cat passwd | awk -F: 'BEGIN{print "begin"} {print$1} END{print "end"}'
      #begin在数据输入之前先执行BEGIN这个块里边的;END是所有数据处理完了再执行这个块里边的东西;
      begin
      ...
      end

     [kris@hadoop datas]$ cat passwd
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon:x:2:2:daemon:/sbin:/sbin/nologin
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      sync:x:5:0:sync:/sbin:/bin/sync
      shutdown:x:6:0:sh.....

    [root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3} END{print "Sum="sum}'  #把第3列的数值加到sum上,对文件的第3列做累加;
      Sum=0
      Sum=3222
    [root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}' ###上面求和的过程
    
    
    [root@kris datas]# which awk
    /bin/awk
    [root@kris datas]# ll /bin/awk
    lrwxrwxrwx. 1 root root 4 9月   3 2013 /bin/awk -> gawk  
    [root@kris datas]# cat passwd | awk -F: -v sum=0 'BEGIN{print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}'  #-v就是引入一个变量
    
    
    awk的内置变量
    [root@kris datas]# cat temp | awk 'BEGIN{sum=0}{sum+=1}/^$/{print sum}'  #打印出文件的所有空行的行号,下面这种方法更简单;
    
    [root@kris datas]# cat temp | awk '/^$/{print NR}' #NR就起到sum的作用; 也可这样写: awk '/^$/{print NR}' temp
    2
    3
    5
    7
    8
    10
    11
    12
    
    [root@kris datas]# awk '/^$/{print FILENAME}' temp  ##每列输出文件名
    temp
    temp
    temp
    
    
    [root@kris datas]# awk -F : '{print NF}' passwd   #######NF是按:切割的列数,一共多少列;  
    7
    7
    7
    ...
    
    [root@kris datas]# awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:"NF}' passwd 
    filename:passwd, linenumber:1,columns:7
    filename:passwd, linenumber:2,columns:7
    filename:passwd, linenumber:3,columns:7
    [root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}'
    192.168.1.100  Bcast
    [root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
    192.168.1.100
    一个目录下(包括子目录)一共有多少个java文件? 如何取得每一个文件的名称? 
    [kris@hadoop ~]$ sudo find / -name "*.java"
    /root/anaconda3/pkgs/spyder-3.3.2-py37_0/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
    /root/anaconda3/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
    [kris@hadoop ~]$ sudo find / -name "*.java" | awk -F "/" '{print $NF}'  以/切割,NF这行一共有多少列,如一共8列,$NF表取第8列
    example.java
    example.java

     [kris@hadoop ~]$ basename /opt/module/hive
      hive

     

     practice 

    使用Linux命令查询file1中空行所在的行号
    [krs@hadoop101 datas]$ awk '/^$/{print NR}' file1.txt 
    5
    1.有文件chengji.txt内容如下:
    张三 40
    李四 50
    王五 60
    
    使用Linux命令计算第二列的和并输出
    [kris@hadoop datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'   ######### -F " " $2 分割的列不是从0开始数的,从1开始
    150
    
    2.用shell写一个脚本,对文本中无序的一列数字排序
    [kris@hadoop datas]$ sort -n text.txt 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    [kris@hadoop datas]$ sort -n text.txt | awk '{sum+=$0; print $0} END{print "sum="sum}'

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      sum=55

    3 用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”kris”的文件名称
      [kris@hadoop datas]$ grep -r "kris" /home/ | cut -d : -f 1

    sort

    -n(依照数值的大小排序) 、  -r (以相反的顺序来排序) 、 -t (设置排序时所用的分隔字符) 、 -k(指定需要排序的列)

    [root@kris datas]# cat passwd | grep ^a | sort -t : -k 3
    avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
    abrt:x:173:173::/etc/abrt:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    apache:x:48:48:Apache:/var/www:/sbin/nologin
    [root@kris datas]#
    cat passwd | grep ^a | sort -t : -k 3 -n   adm:x:3:4:adm:/var/adm:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin
    [root@kris datas]#
    cat passwd | grep ^a | sort -t : -k 3 -nr abrt:x:173:173::/etc/abrt:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin [root@kris datas]# sort -t : -nrk 3 sort.sh bb:40:5.4 bd:20:4.2 cls:10:3.5 xz:50:2.3 ss:30:1.6



  • 相关阅读:
    [git 学习篇] git commit原理 --实践体会
    [git 学习篇]工作区和暂存区
    [git 学习篇] git文件版本回退再学习
    [git 学习篇]版本回退
    [git 学习篇] 修改文件
    [git 学习篇] 提交文件
    [git 学习篇] --创建git创库
    [测试框架学习] 测试框架的结构包含
    [python测试框架] http接口测试框架
    向SharePoint页面添加后台代码
  • 原文地址:https://www.cnblogs.com/shengyang17/p/10268907.html
Copyright © 2011-2022 走看看