第三十三章: 流控制: for循环

在新版bash中, for命令存在两种形式.

33.1 for: 传统shell形式

最原始的for命令语法如下:

for variable [in words]; do
    commands
done

其中variable是一个在循环时会增值的变量名, words是一列将按顺序赋值给变量variable的可选项, commands是每次循环时都会执行的命令. 例如:

for i in A B C D; do echo $i; done

for命令创建字符列表的方式有多种, 简要介绍如下:

# 花括号扩展
for i in {A..D}; do echo $i; done
# 路径名扩展
for i in distros*.txt; do echo $i; done

也可以使用命令形式:

#!/bin/bash
# longest-word : find longest string in a file
while [[ -n $1 ]]; do
    if [[ -r $1 ]]; then
        max_word=
        max_len=0
        for i in $(strings $1); do
            len=$(echo $i | wc -c)
            if (( len > max_len )); then
                max_len=$len
                max_word=$i
            fi
        done
        echo "$1: '$max_word' ($max_len characters)"
    fi
    shift
done

以上程序中使用strings命令读取文件并产生一个可读文本的字符, 然后使用for命令循环处理每个字符以找到最长的字符.

如果for命令中字符部分的选项被忽略, 则for循环默认处理该位置参数, 使用这种方式修改上述脚本如下:

#!/bin/bash
# longest-word2 : find longest string in a file
for i; do
    if [[ -r $i ]]; then
        max_word=
        max_len=0
        for j in $(strings $i); do
            len=$(echo $j | wc -c)
            if (( len > max_len )); then
                max_len=$len
                max_word=$j
            fi
        done
        echo "$i: '$max_word' ($max_len characters)"
    fi
done

33.2 for: C语言形式

第二种for命令语法类似于C语言形式, 语法如下:

for (( expression1; expression2; expression3 )); do
    commands
done

等价与如下结构:

(( expression1 ))
while (( expression2 )); do
    commands
    (( expression3 ))
done

其中expression1 用来初始化循环条件, expression2 用来决定循环何时结束, expression3 在每次循环末尾执行.

一个典型的应用如下:

#!/bin/bash
# simple_counter : demo of C style for command
for (( i=0; i<5; i=i+1 )); do
    echo $i
done

33.3 本章结尾语

重写report_home_space函数, 为每个用户的主目录提供更多的细节, 并且包含用户的文件总数和子目录总数, 代码如下:

report_home_space () {
    local format="%8s%10s%10s\n"
    local i dir_list total_files total_dirs total_size user_name
    if [[ $(id -u) -eq 0 ]]; then
        dir_list=/home/*
        user_name="All Users"
    else
        dir_list=$HOME
        user_name=$USER
    fi
    echo "<H2>Home Space Utilization ($user_name)</H2>"
    for i in $dir_list; do
        total_files=$(find $i -type f | wc -l)
        total_dirs=$(find $i -type d | wc -l)
        total_size=$(du -sh $i | cut -f 1)
        echo "<H3>$i</H3>"
        echo "<PRE>"
        printf "$format" "Dirs" "Files" "Size"
        printf "$format" "----" "-----" "----"
        printf "$format" $total_dirs $total_files $total_size
        echo "</PRE>"
    done
    return
}

results matching ""

    No results matching ""