2017-10-17 50 views
2

我想弄清楚如何传递逗号分隔的列表作为输入,并让我的函数一次处理一个值。bash脚本 - 如何处理逗号分隔列表作为输入参数的函数

我的功能:

addToWhitelist() 
{ 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo); 
    echo "${_ip}"; 
    read -a arr <<<${_ip}; 
    for i in ${arr[@]}; 
    do 
    exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})"; 
    ${_mongo} ${host}/${db} --eval "$exp" 
    done 
} 

我跑我的脚本是这样的:

./myscript.sh -m add -a pizzahut -i 123.456.790.007,123.456.790.008

我正在进行代码:

#!/usr/local/bin/bash 
set -e 
set -x 

# Usage for getopts 
usage() { 
    echo "Example: $0 -m find -a pizzahut" 
    echo "Example: $0 -m add -a pizzahut -i 10.10.123.456" 
    exit 1; 
} 

while getopts ":m:a:i:" o; do 
    case "${o}" in 
    m) 
    _mode=${OPTARG} 
     if [[ "${_mode}" != find && "${_mode}" != add ]]; then 
     usage 
     fi 
    ;; 
    a) 
    _account=${OPTARG} 
    ;; 
    i) 
    _ip=${OPTARG} 
     set -f 
     IFS=, 
    ;; 
    *) 
     usage 
     ;; 
    esac 
done 
shift $((OPTIND-1)) 


getWhitelist() 
{ 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo); 
    exp="db.account.find({\"account\":'${_account}'},{ip_list: 1}).pretty();"; 
    ${_mongo} ${host}/${db} --eval "$exp" 
} 

# Read a list 
addToWhitelist() 
{ 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo); 
    echo "${_ip}"; 
    read -a arr <<<${_ip}; 
    for i in ${arr[@]}; 
    do 
    exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})"; 
    ${_mongo} ${host}/${db} --eval "$exp" 
    done 
} 


case "${_mode}" in 
    'find') 
     echo "Finding information for the account ${_account}" 
     getWhitelist 
     ;; 
    'add') 
     echo "Adding the following IP: ${_ip}" 
     addToWhitelist 
     ;; 
esac 

set +x 

不过,我遇到的问题当我调用该函数时,将值插入单个字符串:

"ip_list" : [ 
    "123.456.790.006", 
    "123.456.790.007,123.456.790.008", 
    "123.456.790.009" 
    ] 
} 

期待:

"ip_list" : [ 
    "123.456.790.006", 
    "123.456.790.007", 
    "123.456.790.008", 
    "123.456.790.009" 
    ] 
} 

回答

1

因为你的脚本接收到一个逗号分隔的IP地址列表,有效的是这样的:

_ip="123.456.790.007,123.456.790.008" 

你需要,分裂列表,并给它蒙戈的$each操作之前报价包装每个IP。

首先,本地化的IFS重新定义到read命令只,然后利用重用相同的格式字符串时提供更多的参数(该膨胀阵列"${arr[@]}"),经由-v选项将结果存储到一个变量的printf的行为,和钢带从结果前导,

IFS=, read -a arr <<<"${_ip}" 
printf -v ips ',"%s"' "${arr[@]}" 
ips="${ips:1}" 

对于上面给出的_ip值,该脚本将存储在ips变量:

"123.456.790.007","123.456.790.008" 

因此,将其应用到你的程序,首先改变你的i)情况下,如:

case "${o}" in 
    # ... 
    i) _ip=${OPTARG};; 
esac 

然后修复addToWhitelist功能:

addToWhitelist() { 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo) 
    IFS=, read -a arr <<<"${_ip}" 
    printf -v ips ',"%s"' "${arr[@]}" 
    ips="${ips:1}" 
    exp="db.account.update({'account': '${_account}'}, {\$addToSet:{'ip_list': {\$each:[$ips]}}})"; 
    "${_mongo}" "${host}/${db}" --eval "$exp" 
} 
+1

哇!非常感谢你的帮助。使用'printf'是处理这个问题的好方法。我感谢您的帮助! – noober

0

以下尝试,

IP = $(回声$ {OPTARG} | sed的 “S /,/,\ N/G”)

所以完整的脚本就会这样,

#!/usr/local/bin/bash 
set -e 
set -x 

# Usage for getopts 
usage() { 
    echo "Example: $0 -m find -a pizzahut" 
    echo "Example: $0 -m add -a pizzahut -i 10.10.123.456" 
    exit 1; 
} 

while getopts ":m:a:i:" o; do 
    case "${o}" in 
    m) 
    _mode=${OPTARG} 
     if [[ "${_mode}" != find && "${_mode}" != add ]]; then 
     usage 
     fi 
    ;; 
    a) 
    _account=${OPTARG} 
    ;; 
    i) 
    _ip=$(echo ${OPTARG}|sed "s/,/,\n/g") 
     set -f 
     IFS=, 
    ;; 
    *) 
     usage 
     ;; 
    esac 
done 
shift $((OPTIND-1)) 
getWhitelist() 
{ 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo); 
    exp="db.account.find({\"account\":'${_account}'},{ip_list: 1}).pretty();"; 
    ${_mongo} ${host}/${db} --eval "$exp" 
} 

# Read a list 
addToWhitelist() 
{ 
    host='127.0.0.1' 
    db='mytest' 
    _mongo=$(which mongo); 
    echo "${_ip}"; 
    read -a arr <<<${_ip}; 
    for i in ${arr[@]}; 
    do 
    exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})"; 
    ${_mongo} ${host}/${db} --eval "$exp" 
    done 
} 


case "${_mode}" in 
    'find') 
     echo "Finding information for the account ${_account}" 
     getWhitelist 
     ;; 
    'add') 
    echo "Adding the following IP: ${_ip}" 
     addToWhitelist 
     ;; 
esac 

set +x 
+0

感谢您的答复。我尝试过,但没有运气。我'回声'看到输出和它仍然是一样的。 '123.456.790.007,123.456.790.008' – noober

+0

你可以用'echo -e $ {OPTARG} | sed“s /,/,\ n/g”'来尝试吗? –

+0

这是我的输出 - 'echo -e $ {OPTARG} | sed“s /,/,\ n/g”''123.456.790.016,n123.456.790.017' – noober

相关问题