• Linux&shell之结构化命令进阶


    写在前面:案例、常用、归类、解释说明。(By Jim)

     for命令
    重复一系列的命令是一种常见的编程实践。

    #!/bin/bash
    # basic for command
    for test in A B C D E F G H I J K L M N O P Q
    do
      echo The next letter is $test
    done

    结果:
    The next letter is A
    The next letter is B
    The next letter is C
    The next letter is D
    The next letter is E
    The next letter is F
    The next letter is G
    The next letter is H
    The next letter is I
    The next letter is J
    The next letter is K
    The next letter is L
    The next letter is M
    The next letter is N
    The next letter is O
    The next letter is P
    The next letter is Q

    每次for命令将列表中的下一个值赋值给变量test。变量$test可以像for命令语句中
    使用其他脚本变量一样使用。最后一次迭代之后,变量$test在shell脚本的其他部分中仍然有效。它仍然是迭代的最后一个值。
    如下:

    #!/bin/bash
    # basic for command
    for test in A B C D
    do
      echo The next letter is $test
    done
    echo "The last letter is $test"
    test=Z
    echo "Wait,now the letter is $test"

    结果:
    The next letter is A
    The next letter is B
    The next letter is C
    The next letter is D
    The last letter is D
    Wait,now the letter is Z

    单引号会引起问题,如下所示

    #!/bin/bash
    # basic for command
    for test in I don't know if this'll work
    do
      echo "word:$test"
    done

    结果:
    word:I
    word:dont know if thisll
    word:work
    由于单引号的存在出现问题了,有两种方法解决这个问题:
    使用转义字符来转义单引号;
    或使用双引号来定义使用单引号的值。
    两种方法都不是很好。

    #!/bin/bash
    # basic for command
    for test in I don't know if this'll work
    do
      echo "word:$test"
    done
    或
    #!/bin/bash
    # basic for command
    for test in I "don't" know if "this'll" work  
    do
      echo "word:$test"
    done

    如果有的数据之间有空格,可以通过双引号括起来
    如下:

    #!/bin/bash
    # basic for command
    for test in Nevada New Hampshire New Mexico New York North Carolina
    do
      echo "Now going to $test"
    done

    结果:
    Now going to Nevada
    Now going to New
    Now going to Hampshire
    Now going to New
    Now going to Mexico
    Now going to New
    Now going to York
    Now going to North
    Now going to Carolina
    但是这并不是我们想要到结果,解决办法

    #!/bin/bash
    # basic for command
    for test in Nevada "New Hampshire" "New Mexico" "New York" "North Carolina"
    do
      echo "Now going to $test"
    done

    结果:
    Now going to Nevada
    Now going to New Hampshire
    Now going to New Mexico
    Now going to New York
    Now going to North Carolina

    从变量读取列表

    #!/bin/bash
    # using a variable to hold the list
    list="Beijing Shanghai Guangzhou Shenzhen Nanjing Hangzhou"
    list=$list" Suzhou"
    
    for city in $list
    do
      echo "Have you ever visited $city"
    done

    结果:
    Have you ever visited Beijing
    Have you ever visited Shanghai
    Have you ever visited Guangzhou
    Have you ever visited Shenzhen
    Have you ever visited Nanjing
    Have you ever visited Hangzhou
    Have you ever visited Suzhou

    读取命令中的值
    生成列表中使用的值的另一种方法是使用命令的输出。
    如下:

    #!/bin/bash
    # reading values from a file
    file="cities"
    
    for city in `cat $file`
    do
      echo "Have you ever visited $city"
    done

    文件cities中的内容
    Nanjing
    Shang hai
    Beijing
    Shenzhen
    Suzhou
    Guangzhou
    结果:
    Have you ever visited Nanjing
    Have you ever visited Shang
    Have you ever visited hai
    Have you ever visited Beijing
    Have you ever visited Shenzhen
    Have you ever visited Suzhou
    Have you ever visited Guangzhou

    问题,这里有空格的话,就会被分成两个输出比如Shang hai 被分成了两个Shang 和hai
    怎么解决呢?下面讲解
    默认情况下,bash shell将下面的字符看作字段分隔符:空格,制表符,换行符
    可以在shell脚本中暂时更改环境变量IFS的值。例如:

    #!/bin/bash
    # reading values from a file
    file="cities"
    
    IFS=$'
    '
    for city in `cat $file`
    do
      echo "Have you ever visited $city"
    done

    这个时候就会把空格排除在外了

    使用通配符读取目录

    #!/bin/bash
    #iterate through all the files in a directory
    
    for file in /home/* /home/jiqing9006/shellscript/*
    do
      if [ -d "$file" ]
      then
        echo "$file is a directory"
      elif [ -f "$file" ]
      then
        echo "$file is a file"
      fi
    done

    结果:
    /home/jiqing9006 is a directory
    /home/lost+found is a directory
    /home/test is a directory
    /home/wghan is a directory
    /home/jiqing9006/shellscript/cities is a file
    /home/jiqing9006/shellscript/test1 is a file
    /home/jiqing9006/shellscript/test10 is a file
    /home/jiqing9006/shellscript/test11 is a file
    ...

    C式的for命令

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

    使用多个变量

    #!/bin/bash
    #testing the C-style for loop
    for((a=1,b=10;a<=10;a++,b--))
    do
      echo "$a-$b"
    done

    结果:
    1-10
    2-9
    3-8
    4-7
    5-6
    6-5
    7-4
    8-3
    9-2
    10-1

    #!/bin/bash
    #testing the C-style for loop
    for((a=1,b=10;a<=10;a++,b--))
    do
      echo $[ $a-$b ]
    done

    这样就会计算值了

    While循环

    #!/bin/bash
    # while command test
    var1=10
    while [ $var1 -gt 0 ]
    do
      echo $var1
      var1=$[ $var1 - 1 ]
    done


    多条件

    #!/bin/bash
    # while command test
    var1=10
    while echo $var1
          [ $var1 -gt 0 ]
    do
      echo "This is inside the loop"
      var1=$[ $var1 - 1 ]
    done

    结果
    10
    This is inside the loop
    9
    This is inside the loop
    8
    This is inside the loop
    7
    This is inside the loop
    6
    This is inside the loop
    5
    This is inside the loop
    4
    This is inside the loop
    3
    This is inside the loop
    2
    This is inside the loop
    1
    This is inside the loop
    0

    until命令
    until命令刚好与while命令相反。until命令需要制定一条测试命令,这条命令通常产生一个非零的退出状态。
    只要测试命令的退出状态非零,bash就会执行列在循环当中的命令。一旦为0,循环停止。

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

    将不会执行,因为符合了大于0的条件,这个与while是相反的

    嵌套循环

    #!/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

    (这里面空格就没那么重要了,都识别的)

    结果:
    Starting loop 1:
    Inside loop:1
    Inside loop:2
    Inside loop:3
    Starting loop 2:
    Inside loop:1
    Inside loop:2
    Inside loop:3
    Starting loop 3:
    Inside loop:1
    Inside loop:2
    Inside loop:3

    混合循环

    #!/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

    结果:
    Outer loop:5
    Inner loop:5*1 = 5
    Inner loop:5*2 = 10
    Outer loop:4
    Inner loop:4*1 = 4
    Inner loop:4*2 = 8
    Outer loop:3
    Inner loop:3*1 = 3
    Inner loop:3*2 = 6
    Outer loop:2
    Inner loop:2*1 = 2
    Inner loop:2*2 = 4
    Outer loop:1
    Inner loop:1*1 = 1
    Inner loop:1*2 = 2
    Outer loop:0
    Inner loop:0*1 = 0
    Inner loop:0*2 = 0

    再来看一下until与while结合的,准备晕吧少年

    #!/bin/bash
    #using until and while loops
    var1=3
    until [ $var1 -eq 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 ]
    done

    #外循环执行三次,内循环每执行四次
    结果:
    Outer loop:3
      Inner loop:3/1 = 3.0000
      Inner loop:3/2 = 1.5000
      Inner loop:3/3 = 1.0000
      Inner loop:3/4 = .7500
    Outer loop:2
      Inner loop:2/1 = 2.0000
      Inner loop:2/2 = 1.0000
      Inner loop:2/3 = .6666
      Inner loop:2/4 = .5000
    Outer loop:1
      Inner loop:1/1 = 1.0000
      Inner loop:1/2 = .5000
      Inner loop:1/3 = .3333
      Inner loop:1/4 = .2500
    控制循环
    break&continue

    #!/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 "number:$var1"
    done
    echo "The for loop is completed"

    同样适用于while循环

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

    (循环到等于5的时候,就停止了)

    跳出内循环

    #!/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

    结果:
    Outer loop:1
      Inner loop:1
      Inner loop:2
      Inner loop:3
      Inner loop:4
    Outer loop:2
      Inner loop:1
      Inner loop:2
      Inner loop:3
      Inner loop:4
    Outer loop:3
      Inner loop:1
      Inner loop:2
      Inner loop:3
      Inner loop:4
      (跳出了内部循环,但是外部循环继续进行)

    跳出外部循环
    break n,默认n是1,代表跳出当前循环。如果将n设置为2,将停止外循环的下一级循环。

    #!/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 2
        fi
        echo "  Inner loop:$b"
      done
    done

    结果:
    Outer loop:1
      Inner loop:1
      Inner loop:2
      Inner loop:3
      Inner loop:4
      (跳出了外部循环,当然本次的循环也终止了)

    continue命令

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

    结果:
    Iteration number:1
    Iteration number:2
    Iteration number:3
    Iteration number:4
    Iteration number:5
    Iteration number:10
    Iteration number:11
    Iteration number:12
    Iteration number:13
    Iteration number:14
    (循环没有终止,只是跳过了,继续下一次循环)


    #!/bin/bash
    # using the continue command
    
    for((a=1;a<=5;a++))
    do
      echo "Iteration $a:"
      for((b=1;b<=10;b++))
      do
        if [ $a -gt 3 ]&&[ $b -lt 5 ]
        then
          continue
        fi
        res=$[ $a*$b ]
        echo "The result of $a*$b is:$res"
      done
    done

    (这个时候,会在a为4时或5时,的大循环中断掉b小于5的几个计算)

    #!/bin/bash
    # using the continue command
    
    for((a=1;a<=5;a++))
    do
      echo "Iteration $a:"
      for((b=1;b<=10;b++))
      do
        if [ $a -gt 3 ]&&[ $b -lt 5 ]
        then
          continue 2
        fi
        res=$[ $a*$b ]
        echo "The result of $a*$b is:$res"
      done
    done

    (这里直接跳过a为4或5的内循环,连b大于5的内容也不显示了)

    #!/bin/bash
    # using the continue command
    
    for((a=1;a<=5;a++))
    do
      echo "Iteration $a:"
      for((b=1;b<=10;b++))
      do
        if [ $a -gt 3 ]&&[ $b -lt 5 ]
        then
          break
        fi
        res=$[ $a*$b ]
        echo "The result of $a*$b is:$res"
      done
    done

    (跳出a为4或5的内循环,效果等同于continue 2)

    #!/bin/bash
    # using the continue command
    
    for((a=1;a<=5;a++))
    do
      echo "Iteration $a:"
      for((b=1;b<=10;b++))
      do
        if [ $a -gt 3 ]&&[ $b -lt 5 ]
        then
          break 2
        fi
        res=$[ $a*$b ]
        echo "The result of $a*$b is:$res"
      done
    done

    (直接跳出之后的动作,跳出外循环也终止了)

    处理循环的输出

    #!/bin/bash
    # using the continue command
    
    for((a=1;a<=5;a++))
    do
      echo "Iteration $a:"
      for((b=1;b<=10;b++))
      do
        if [ $a -gt 3 ]&&[ $b -lt 5 ]
        then
          break
        fi
        res=$[ $a*$b ]
        echo "The result of $a*$b is:$res"
      done
    done > output.txt

    (会将循环得到的结果写入output.txt文档下)

  • 相关阅读:
    hadoop大数据平台架构之DKhadoop详解
    越狱设备看不到系统文件夹
    iOS开发 调试 网络限速
    关于OCMock的一些事儿
    Cannot proceed with delivery: an existing transporter instance is currently uploading this package
    windows安装nose
    IE6支持png半透明图片
    ie下web常见错误和差异及解决方案
    js,php下 css颜色加深、减淡,css颜色递进的方法
    html+css div百分百占满正行的两种方法
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/3200648.html
Copyright © 2020-2023  润新知