美文网首页
Linux 命令 & shell 脚本之06(for、while

Linux 命令 & shell 脚本之06(for、while

作者: 轻飘飘D | 来源:发表于2020-09-28 10:34 被阅读0次

    命令格式:

    for var in list; do
       commands
    done
    
    1. 读取列表中的值
    $ cat test1 
    #!/bin/bash 
    # basic for command 
    for test in Alabama California Colorado; do 
      echo The next state is $test 
    done 
    $ ./test1 
    The next state is Alabama 
    The next state is California 
    The next state is Colorado
    

    1.1 讀取數組中的值

    --------------------------------------------------
    for 循環讀取方法
    for i in ${variable[@]}; do
        # do something....
    done
    --------------------------------------------------
    [oracle@DB02 myshell]$ cat test_array.sh 
    #!/bin/bash 
    # basic for command 
    #
    arr=("aa" "bb" "cc")   
    echo "所有的内容如下:" ${arr[@]}   
    #数组的下标从0开始
    echo "第 2 個 元素值:" ${arr[1]}  
    echo "数组的长度方法1:" ${#arr[*]} 
    echo "数组的长度方法2:" ${#arr[@]}  
    
    for var in ${arr[@]}; do
       echo "打印的内容:" $var 
    done
    
    [oracle@DB02 myshell]$ ./test_array.sh 
    所有的内容如下: aa bb cc
    第 2 個 元素值: bb
    数组的长度方法1: 3
    数组的长度方法2: 3
    打印的内容: aa
    打印的内容: bb
    打印的内容: cc
    

    1.2 讀取字典中的值

    [oracle@DB02 15]$ cat test_dict.sh 
    #!/bin/bash 
    #
    echo "shell定义字典"
    #必须先声明
    declare -A dic
    #dic=([key1]="value1" [key2]="value2" [key3]="value3")
    
    dic["key1"]="values1"
    dic["key3"]="values3"
    dic["key5"]="values5"
    
    #打印指定key的value
    echo ${dic["key1"]}
    #打印所有key值
    echo ${!dic[*]}
    #打印所有value
    echo ${dic[*]}
    
    #遍历key值
    for key in $(echo ${!dic[*]}); do
        echo "$key : ${dic[$key]}"
    done
    ---------------------------------------------------------------
    [oracle@DB02 15]$ ./test_dict.sh 
    shell定义字典
    values1
    key5 key3 key1
    values5 values3 values1
    key5 : values5
    key3 : values3
    key1 : values1
    
    
    1. 读取列表中的复杂值(列表值中含单引号)
    有两种办法可解决这个问题:
     使用转义字符(反斜线)来将单引号转义;
     使用双引号来定义用到单引号的值
    
    $ cat test2 
    #!/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 
    
    $ ./test2 
    word : I 
    word : don't 
    word : know 
    word : if 
    word : this'll 
    word : work
    #在第一个有问题的地方添加了反斜线字符来转义don't中的单引号。在第二个有问题的地方将this'll用双引号圈起来。两种方法都能正常辨别出这个值
    
    #for命令用空格来划分列表中的每个值。如果在单独的数据值中有空格,就必须用双引号将这些值圈起来
    $ cat test3 
    #!/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 
    
    $ ./test3 
    Now going to Nevada 
    Now going to New Hampshire 
    Now going to New Mexico 
    Now going to New York
    
    1. 从变量读取列表
    $ cat test4 
    #!/bin/bash 
    # using a variable to hold the list 
    list="Alabama Colorado" 
    list=$list" Connecticut" 
    
    for state in $list; do 
      echo "Have you ever visited $state?" 
    done 
    
    $ ./test4 
    Have you ever visited Alabama? 
    Have you ever visited Colorado? 
    Have you ever visited Connecticut?
    
    1. 从命令读取值 & 更改字段分隔符
    默认情况下,bash shell会将下列字符当作字段分隔符:
     空格
     制表符
     换行符
    在处理可能含有空格的数据时可以在shell脚本中临时更改IFS环境变量的值来限制被bash shell当作字段分隔符的字符。
    例如,如果你想修改IFS的值,使其只能识别换行符(告诉bash shell在数据值中忽略空格和制表符),那就必须这么做:
    IFS=$'\n'
    
    案例1
    $ cat test5b 
    #!/bin/bash 
    # reading values from a file 
    file="states" 
    IFS=$'\n' 
    for state in $(cat $file); do 
      echo "Visit beautiful $state" 
    done
    
    $ cat states 
    Alabama 
    Colorado 
    Delaware 
    New York
    North Carolina
    
    $ ./test5b 
    266 第 13 章 更多的结构化命令
    Visit beautiful Alabama 
    Visit beautiful Colorado 
    Visit beautiful Delaware 
    Visit beautiful New York 
    Visit beautiful North Carolina
    
    你要做的就是将IFS的值设为冒号。
    IFS=: 
    如果要指定多个IFS字符,只要将它们在赋值行串起来就行。
    IFS=$'\n':;" 
    这个赋值会将换行符、冒号、分号和双引号作为字段分隔符
    
    1. 用通配符读取目录
    应该将$file变量用双引号圈起来。如果不这么做,遇到含有空格的目录名或文件名时就会有错误产生
    $ cat test6 
    #!/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 
    
    $ ./test6 
    /home/rich/test/dir1 is a directory 
    /home/rich/test/myprog.c is a file 
    /home/rich/test/testprog.c is a file
    

    6.bash中C语言风格的for循环

    基本格式:
    for (( variable assignment ; condition ; iteration process ))
    do
      ...
    done 
    
    or 
    for (( variable assignment ; condition ; iteration process )); do
      ...
    done 
    
    案例
    $ cat test8 
    #!/bin/bash 
    # testing the C-style for loop 
    for (( i=1; i <= 5; i++ )) 
    do 
      echo "The next number is $i" 
    done 
    
    $ ./test8 
    The next number is 1 
    The next number is 2 
    The next number is 3 
    The next number is 4 
    The next number is 5
    
    使用多个变量:
    可以为每个变量定义不同的迭代过程。尽管可以使用多个变量,但你只能在for循环中定义一种条件
    $ cat test9 
    270 第 13 章 更多的结构化命令
    #!/bin/bash 
    # multiple variables 
    for (( a=1, b=10; a <= 10; a++, b-- )); do 
       echo "$a - $b" 
    done 
    
    $ ./test9 
    1 - 10 
    2 - 9 
    ...
    9 - 2 
    10 - 1
    
    1. while 命令
    while命令的格式是:
    while test command 
    do 
     other commands 
    done
    
    $ cat test10 
    #!/bin/bash 
    # while command test 
    var1=10 
    
    while [ $var1 -gt 0 ] 
    do 
      echo $var1 
      var1=$[ $var1 - 1 ] 
    done 
    
    $ ./test10 
    10 
    9 
    ...
    2 
    1 
    
    1. until 命令
    until命令的格式如下。
    until test commands 
    do 
      other commands 
    done
    
    案例:
    $ cat test12 
    #!/bin/bash 
    # using the until command 
    var1=100 
    until [ $var1 -eq 0 ] 
    do 
      echo $var1 
      var1=$[ $var1 - 25 ] 
    done 
    
    $ ./test12 
    100 
    75 
    50 
    25
    
    1. 案例-循环处理文件数据
    典型的例子是处理/etc/passwd文件中的数据。这要求你逐行遍历/etc/passwd文件,
    并将IFS变量的值改成冒号,这样就能分隔开每行中的各个数据段了
    
    #!/bin/bash 
    # changing the IFS value 
    IFS.OLD=$IFS 
    IFS=$'\n' 
    for entry in $(cat /etc/passwd) 
    do 
       echo "Values in $entry –" 
       IFS=: 
    
       for value in $entry 
       do 
         echo " $value" 
       done 
    done
    
    在运行这个脚本时,你会得到如下输出。
    Values in rich:x:501:501:Rich Blum:/home/rich:/bin/bash - 
     rich 
     501 
     501 
     Rich Blum 
     /home/rich 
     /bin/bash 
     Values in katie:x:502:502:Katie Blum:/home/katie:/bin/bash - 
     katie 
     x 
     506 
     509 
     Katie Blum 
     /home/katie 
     /bin/bash
    
    1. break 命令 (用break命令来退出任意类型的循环,包括while和until循环)
      10.1 跳出单个循环
    $ cat test17 
    #!/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"
    
     ./test17 
    Iteration number: 1 
    Iteration number: 2 
    Iteration number: 3 
    Iteration number: 4 
    The for loop is completed
    
    $ cat test18 
    #!/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" 
    
    $ ./test18 
    Iteration: 1 
    Iteration: 2 
    Iteration: 3 
    Iteration: 4 
    The while loop is completed
    

    10.2 跳出内部循环

    $ cat test19 
    #!/bin/bash 
    # breaking out of an inner loop 
    for (( a = 1; a < 3; 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 
    
    $ ./test19 
    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 
    

    10.3 跳出外部循环

    有时你在内部循环,但需要停止外部循环。break命令接受单个命令行参数值:
    break n
    
    其中n指定了要跳出的循环层级。默认情况下,n为1,表明跳出的是当前的循环。如果你将n设为2,
    break命令就会停止下一级的外部循环
    
    $ cat test20 
    #!/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 3 ] 
       then 
         break 2 
       fi 
       echo " Inner loop: $b" 
     done 
    done 
    
    $ ./test20 
    Outer loop: 1 
     Inner loop: 1 
     Inner loop: 2 
     Inner loop: 3
    
    1. continue 命令
    $ cat test21 
    #!/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 
    $ ./test21 
    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
    
    和break命令一样,continue命令也允许通过命令行参数指定要继续执行哪一级循环:
    continue n
    其中n定义了要继续的循环层级。下面是继续外部for循环的一个例子:
    
    $ cat test22 
    #!/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 
    
    $ ./test22 
    Iteration 1: 
     The result of 1 * 1 is 1 
     The result of 1 * 2 is 2 
    Iteration 2: 
     The result of 2 * 1 is 2 
     The result of 2 * 2 is 4 
    Iteration 3: 
    Iteration 4: 
     The result of 4 * 1 is 4 
     The result of 4 * 2 is 8 
    Iteration 5: 
     The result of 5 * 1 is 5 
     The result of 5 * 2 is 10
    
    1. 对循环的输出使用管道或进行重定向
    $ cat test23 
    #!/bin/bash
    # redirecting the for output to a file 
    for (( a = 1; a < 6; a++ )); do 
      echo "The number is $a" 
    done > test23.txt 
    echo "The command is finished." 
    
    $ ./test23 
    The command is finished. 
    $ cat test23.txt 
    The number is 1 
    The number is 2 
    The number is 3 
    The number is 4 
    The number is 5 
    
    $ cat test24 
    #!/bin/bash 
    # piping a loop to another command 
    for state in "North Dakota" Connecticut Alabama; do 
      echo "$state is the next place to go" 
    done | sort 
    echo "This completes our travels" 
    
    $ ./test24 
    Alabama is the next place to go 
    Connecticut is the next place to go 
    North Dakota is the next place to go 
    This completes our travels
    

    相关文章

      网友评论

          本文标题:Linux 命令 & shell 脚本之06(for、while

          本文链接:https://www.haomeiwen.com/subject/kvgqyktx.html