【原创】foreach() 函数

【原创】foreach() 函数

经常需要对 n 个“变量”执行相同的操作,又觉得 for 的语法不够简洁,近日自己实现了一个函数 foreach(),用了几天感觉还不错      
用法示例:
复制内容到剪贴板
代码:
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color] foreach "a  b" c    # command 默认为 echo
--- command 0: echo a  b
a b
--- command 1: echo c
c
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color] foreach "a  b" c do    # command 默认为 echo
--- command 0: echo a  b
a b
--- command 1: echo c
c
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color] foreach "a  b" c do echo {}    # 默认用 {} 表示每个“元素”
--- command 0: echo a  b
a b
--- command 1: echo c
c
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color] foreach "a  b" c do echo '"{}"'
--- command 0: echo "a  b"
a  b
--- command 1: echo "c"
c
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color] foreach -ixx "a  b" c do echo '"xx"'    # 用 xx 表示每个“元素”
--- command 0: echo "a  b"
a  b
--- command 1: echo "c"
c
[color=blue]-(guest@mac:tty1)-(tmp)-
[10426 0] %[/color]
      
Code updated:
复制内容到剪贴板
代码:
#
# Note: Part of the idea stolen from xargs
#
foreach()
{
    if [ $# = 0 ]; then
        $FUNCNAME -h
        return 1
    fi

    local replace="{}"
    local option
    declare -i i j verbose
    declare -a words cmdPattern cmd

    OPTIND=1
    OPTERR=0
    verbose=0
    while getopts ":hi:v" option "$@"; do
        case $option in
            h|"?"|:)
            {
                echo "Usage:"
                echo "    $FUNCNAME [-h] [-i replace-str] [-v] WORDS ... [do [COMMANDS ...]]"
                echo ""
                echo "Options:"
                echo "    -h    Help"
                echo "    -i replace-str"
                echo "          Replace occurences of \`replace-str' in the COMMANDS with word"
                echo "          from WORDS. Only char in [a-z] can occur in \`replace-str'."
                echo "    -v    Verbose mode"
                echo ""
                echo "Report bugs to $ESC[1;35mWang Jian <dearvoid AT 263 DOT net>$ESC[0m"
                [ "$option" = h ] && return 0 || return 1
            };;

            i)
            {
                replace=$OPTARG
                if [ ! "$replace" ] || echo "$replace" | command grep -q "[^a-z]"; then
                    $FUNCNAME -h
                    return 1
                fi
            };;

            v)
            {
                verbose=1
            };;
        esac
    done
    shift $((OPTIND - 1))

    for ((i = 0; $# > 0; ++i)); do
        if [ "$1" != do ]; then
            words[i]=$1
            shift
        else
            shift
            break
        fi
    done

    if [ $# -gt 0 ]; then
        cmdPattern=("$@")
    else
        cmdPattern=(echo "$replace")
    fi

    for ((i = 0; i < ${#words[*]}; ++i)); do
        for ((j = 0; j < ${#cmdPattern[@]}; ++j)); do
            cmd[j]=${cmdPattern[j]//$replace/${words[i]}}
        done
        ((verbose)) && echo "[$ESC[1;35m$((i + 1))$ESC[0m] \$ ${cmd[@]}"
        eval "${cmd[@]}"
    done
}