zoukankan      html  css  js  c++  java
  • 更多的结构化命令

      前面介绍了if和case语句,这一节我们了解for、while和until语句

    1、for命令

      对命令进行重复执行,是编程思想中的常见方式。

      bash shell提供了for命令,来重复执行一组命令:

        for var in list 

        do

          commands

        done

      参数list用于提供一些用于迭代的值。

      1.1、读取列表中的值

        给变量test轮流复制;

    #!/bin/bash
    #basic for command
    for test in Alabama Alaska Alaska Arizona Arkansas California Colorado
    do
        echo The next state is $test
    done

        最后一个值,colorado赋值完成以后,会继续向下运行脚本程序

    #!/bin/bash
    #testing the for variable after the looping
    
    for test in Alabama Alaska Ariziona Arkansas California Colorado
    do 
        echo "The next state is $test"
    done
    echo "The last state we visited was $test"
    test=Connecticut
    ehco "Wait,now we're visiting $test"

      1.2、读取列表中的复杂值

        事情不会那么简单,以下实例说明一个麻烦:

    #!/bin/bash
    #another example of how not to use the fo command
    
    for test in I don't know if this'll work
    do 
        echo "word:$test"
    done

        其中 't know if this' 被识别为了一个字符串,同时赋值给了test

        解决方法:1、使用转意字符;2、使用双引号来定义使用的单引号的值;

    #!/bin/bash
    #another example of how not to use the for command
    for test in I don't know if "this'll" work
    do 
        echo "word:$test"
    done

        所以,我们需要技术,for循环中每个值都是用空格隔开的。我们就需要用双引号引起来;

    #!/bin/bash
    #an example of how to properly define values
    
    for test in Nevada "New Hampshire" "New Mexico" "New York"
    do
        echo "Now going to $test"
    done

      1.3、从变量读取列表

        我们会将列表存储于变量中,让for语句从变量中读取数据;

    #!/bin/bash
    #using a variable to hold the list
    
    list="Alabama Alaska Arizona Arkansas Colorado"
    list=$list" Connecticut"
    
    for state in $list
    do
        echo "Have you ever visited $state?"
    done

      1.4、读取命令中的值

        可以使用反引号来获取命令执行结果,赋值给变量,再对变量进行遍历;

    #!/bin/bash
    #reading values from a file 
    
    file="states"
    
    for state in `cat $file`
    do
        echo "Visit beautiful $state"
    done

        这里注意,states文件中的内容,每一行包含一个转态,用空格隔开。

      1.5、改变字段分隔符

        默认使用空格做分隔符。但是根据IFS--内部字段分割符包括三个:空格、制表符、换行符。

        如何选择其他的符号作为分隔符呢,或者是同时使用多个符号做分隔符呢?

    #!/bin/bash
    #reading values from a file
    
    file="states"
    
    IFS=$`
    `  #IFS值来定义分隔符,可以通过该命令,来改变分隔符;
     表示以回车为分隔符
    for state in `cat $file`
    do
        echo "Visit beautiful $state"
    done

        在工作中对于分隔符的定义方法,先保存原来的分隔符,等在使用时候恢复过来即可

    IFS.OLD=$IFS
    IFS=$`
    `
    <user teh new IFS value in code>
    IFS=$IFS.OLD

        如果想指定多个分隔符

    IFS=$`
    `:;"  #这里使用了回车、冒号、分号、双引号同时作为分隔符

      1.6、使用通配符读取目录

        文件通配符匹配目录

    #!/bin/bash
    #iterate through all the files in a directory
    
    for file in /home/rich/test/*
    do
        if [ -d "$file" ]  #判断文件是否为目录
        then
            echo "$file is a directory"
        elif [ -f "$file" ]  #判断是否为普通文件
        then
            echo "$file is a file"
        fi
    done

        可以出了使用通配符,还可以结合列表

    #!/bin/bash
    #iterating through multiple directories
    
    for file in /home/rich/.b* /home/rich/badtest
    do 
        if [ -d "$file" ]
        then
            echo "$file is a directory"
        elif [ -f "$file" ]
        then
            echo "$file is a file"
        else
            echo "$file doesn't exist"
        fi
    done

    2、C式的for命令

      在C语言中,for循环通常定义一个变量,该变量在每次迭代过程中自动改变值。通常程序员将该变量用做计数器,每次迭代计数器要么增加一个,要么减少一个。bash的for命令也能提供这种功能。

      2.1、C语言中的for命令

        在C语言的循环中,for一直要保持true才能继续运行,直到false,则循环结束

    for (i = 0; i < 10; i++)
    {
        printf("The next number is %d
    ", i);    
    }

        i作为计数器。一直累加,当不符合条件时循环结束;

        bash shell可以使用这种思路,来编写自己的for循环脚本语句;

    格式:for (( variable assignment ; condition ; iteration process ))
    for (( a=1; a<10; a++ ))

        注意,有几项是不遵循bash shell的for方法:1、变量的复制可以包含空格;2、条件中的变量不以$符号做前缀;3、迭代处理式不适用expr命令格式;

        在shell脚本中,使用C式的程序需要谨慎;

    #!/bin/bash
    #testing the C-style for loop
    
    for (( i=1; i <= 10; i++))
    do 
        echo "The next number is $i"
    done

      2.2、使用多个变量

        C式的shell只能在for循环中定义一个条件,是具有局限性的;

    #!/bin/bash
    #multiple variables
    
    for (( a=1, b=10; a <=10 ' a++, b--))
    do
        echo "$a - $b"
    done

    3、while命令

      while命令像是if-then和for的结合体。while是容许要定义测试的命令,只要定义的测试命令返回值为0,就循环一组命令。它在每次迭代开始时检查测试命令,测试命令返回值为非零,while则终止执行命令集;

      3.1、while基本格式

        while命令的格式:

          while test command

          do 

            other commands

          done

        在while语句中,test与if-then语句中的定义格式一样;while的关键是,在运行other commands后一点要改变test转态,否则就会进入死循环;

    #!/bin/bash
    #while command test
    
    var1=10
    while [ $var1 -gt 0 ]  #比较var1值与0的大小
    do
        echo $var1
        var1=$[ $var1 - 1 ]  #每次循环完成都要对var1参数减1才行
    done

      3.2、使用多条测试命令

        while语句容许定义多条test命令。只有最后一条test命令的状态才决定循环何时停止;

    #!/bin/bash
    # testing a multicommand while loop
    
    var1=10
    
    while echo $var1
        [ $var1 -ge 0 ]
    do
        echo "This is inside the loop"
        var1=$[ $var1 - 1 ]
    done

        上面的这个脚本中while的测试语句有两条,ehco $var1和[ $var1 -ge 0 ],所以,最后是否运行do-done中的命令,取决于 [ $var1 -ge 0 ] 这条命令的测试结果

    4、until命令

      until命令刚好和while命令相反。定义一个测试语句,如果返回为非0结果,则运行do-done中的语句,如果是0结果,则不运行do-done中的语句;

      until命令的格式:

        until test commands

        do

          other commands

        done

      与while类似,可以使用多条测试语句,但是依然只有最后条测试语句才生效;

    #!/bin/bash
    # using the until command
    
    var1=100
    
    until [ $var1 -eq 0 ]
    do 
        echo $var1
        var1=$[ $var1 - 25 ]
    done

      一旦结果变为0,则运行结果停止。

    #!/bin/bash
    #using the until command
    
    var1=100
    
    until echo $var1
        [ $var1 -eq 0 ]
    do
        echo Inside the loop: $var1
        var1=$[ $var1 -25 ]
    done

    5、嵌套循环

      一条循环语句可以在循环中使用任何类型的命令,包括其他循环的命令,就是嵌套循环。

      一个for循环中嵌套另一个for循环实例:

    #!/bin/bash
    # nesting for loops
    
    for (( a = 1; a <= 3; a++ ))
    do
        echo "Starting loop $a:"
        for (( b = 1; b <= 3; b++ ))
        do
            echo "Inside loop: $b"
        done
    done

      for循环放在while循环内:

    #!/bin/bash
    # placing a for loop inside a while loop
    
    var1=5
    
    while [ $var1 -ge 0 ]
    do
        echo "Outer loop: $var1"
        for (( var2 = 1; $var2 < 3; var2++ ))
        do
            var3=$[ $var1 * $var2 ]
            echo "Inner loop: $var1 * $var2 = $var3"
        done
        var1=$[ $var1 -1 ]
    done

      until和while循环也是可以结合起来:

    #!/bin/bash
    # using until and while loops
    
    var1=3
    
    until [ $var1 -eq 0 ]  #从3开始,只要不等于0就执行下面的脚本
    do 
        echo "Outer loop: $var1"
        var2=1
        while [ $var2 -lt 5 ]
        do 
            var3=`echo "scale=4; $var1 / $var2" | bc`
            echo "Inner loop: $var1 / $var2 = $var3"
            var2=$[ $var2 + 1 ]
        done
        var1=$[ $var1 - 1 ]  #执行完一次,我们需要对var1 - 1 不能一直循环下去
    done

    6、文件数据的循环

      迭代存储在文件内部的项,需要结合两种介绍过的技术:1、使用嵌套循环;2、更改环境变量IFS;

      通过更改环境变量IFS,可以迫使for命令将文件中的每行作为单独的一项来处理,即使数据含有空格。提取了文件中的个别行之后,您可能还需要再循环已提取其宝行的数据;

      以/etc/passwd文件中处理数据为例:

    #!/bin/bash
    # changing the IFS value
    IFS.OLD=$IFS
    IFS=$`
    `
    for entry in `cat /etc/passwd`
    do
        echo "Values in $entry -"
        IFS=:
        for value in $entry
        do
            echo "$value"
        done
    done

      先取出每行,在再每行上以:为分隔符在取一遍数值;

    7、控制循环

      我们可以通过命令控制循环内部发生的事情。1、break;2、continue;

      这两条命令用于控制循环操作;

      7.1、break

        在循环的过程中,跳出循环的一种简单方法。可以使用break退出任何类型的循环;

        1、跳出单循环

    #!/bin/bash
    # breaking out of a for loop
    
    for var1 in 1 2 3 4 5 6 7 8 9 10
    do 
        if [ $var1 -eq 5 ]
        then
            break 
        fi
        echo "Iteration number: $var1"
    done
    echo "The for loop is completed"

        for循环通常迭代列表中指定的所有值。然而,当if-then条件满足,shell执行break命令就能终止for循环;这种方式同样适用于while和until循环;

    #!/bin/bash
    # breaking out of a while loop
    
    var1=1
    
    while [ $var1 -lt 10 ]
    do
        if [ $var1 -eq 5 ]
        then
            break
        fi
        echo "Iteration: $var1"
        var1=$[ $var1 + 1 ]
    done
    echo "The while loop is completed"

        2、跳出内循环

        使用多循环时break命令自动终止您所在的最里面的内部循环;

    #!/bin/bash
    # breaking out of an inner loop
    
    for (( a = 1; a < 4; a++ ))
    do
        echo "Outer loop: $a"
        for (( b = 1; b < 100; b++ ))
        do
            if [ $b -eq 5 ]
            then
                break
            fi
            echo " Inner loop: $b"
        done
    done

        3、跳出外循环

        可能有时处于内循环单需要停止外循环。break命令宝行单独的命令执行参数;

    #!/bin/bash
    # breaking out of an outer loop
    
    for (( a = 1; a < 4; a++ ))
    do
        echo "Outer loop: $a"
        for (( b = 1; b < 100; b++ ))
        do 
            if [ $b -gt 4 ]
            then
                break 2
            fi
            echo " Inner loop: $b"
        done
    done

        这里 2 数据表示循环级别,当前所处的 循环级别为 1 ;向外一次加。就是 2级循环;

      7.2、continue

        不终止循环,只是跳过这一个循环值,后面的依然继续运行;

        for循环中使用continue

    #!/bin/bash
    # using the contnue command
    
    for (( var1 = 1; var1 < 15; var1++ ))
    do
        if [ $var -gt 5 ] && [ $var1 -lt 10 ]
        then
            continue
        fi
        echo "Iteration number: $var1"
    done

        var1值大于5小于10的话,就被continue跳过了;

        在until和while中使用continue要特别谨慎,不能在键值添加的时候跳过这个添加值的过程;

    #!/bin/bash
    # improperly using the continue command in a while loop
    
    var1=0
    while echo "while iteration: $var1"
            [ $var1 -lt 15 ]
    do
        if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
        then 
            continue
        fi
        echo "Inside iteration number: $var1"
        var1=$[ $var1 + 1 ]
    done

        在大于5小于10的时候跳过了var1自加的过程,则时候就进入了死循环!!!这一点一定要注意;

        同样的,continue命令可以使用 continue n 来指定停止的循环级别;

    #!/bin/bash
    # continuing an outer loop
    
    for (( a = 1; a <= 5; a++ ))
    do 
        echo "Iteration $a:"
        for (( b = 1; b < 3; b++ ))
        do
            if [ $a -gt 2 ] && [ $a -lt 4 ]
            then 
                continue 2
            fi
            var3=$[ $a * $b ]
            echo " The result of $a * $b is $var3"
        done
    done

    8、处理循环输出

      最后,在shell循环中,使用管道和重定向符号处理输出结果;

    for file in /home/rich/*
    do
        if [ -d "$file" ]
        then
            echo "$file is a directory"
        elif
            echo "$file is a file"
        fi
    done > output.txt

      可以将脚本内容重定向到output.txt中,而不是输出到屏幕

    #!/bin/bash
    # redirecting the for output to a file
    
    for (( a = 1; a < 10; a++ ))
    do
        echo "The number is $a"
    done > test23.txt
    echo "The command is finished."

      同样的技术,也可以用于将循环的输出管道传送给其他命令:

    #!/bin/bash
    # piping a loop to another command
    
    for state in "North Dakota" Connecticut Illinois Alabama Tennessee
    do 
        echo "$state is the next place to go"
    done | sort
    echo "This completes our travels"

      for输出的结果传送给sort来进行操作;

  • 相关阅读:
    解决Error:com.intellij.util.indexing.StorageException
    Spring AOP (上)
    spring aop expression简单说明
    Spring AOP 详解
    基于Spring AOP实现对外接口的耗时监控
    JavaEE参考示例 SpringSide 4.0 GA版杀青
    MyBatis学习 之 四、MyBatis配置文件
    MyBatis学习 之 三、动态SQL语句
    MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存
    MyBatis学习 之 二、SQL语句映射文件(1)resultMap
  • 原文地址:https://www.cnblogs.com/BurnovBlog/p/10783575.html
Copyright © 2011-2022 走看看