bash 脚本 - 如何将逗号分隔列表作为函数的输入参数进行处理

标签 bash unix scripting getopts

我正在尝试弄清楚如何将逗号 , 分隔的列表作为输入传递,并让我的函数一次处理一个值。

我的功能:

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"
  ]
}

最佳答案

由于您的脚本接收到以逗号分隔的 IP 列表,因此实际上类似于:

_ip="123.456.790.007,123.456.790.008"

您需要按 , 拆分列表,并在将每个 IP 提供给 Mongo 的 $each 运算符之前将其用引号引起来。

首先,将 IFS 的重新定义仅局限于 read 命令,然后利用 printf 重用相同格式字符串的行为,当更多提供参数(扩展数组 "${arr[@]}"),通过 -v 选项将结果存储到变量,并去除前导 , 从结果:

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"
}

关于bash 脚本 - 如何将逗号分隔列表作为函数的输入参数进行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46782689/

相关文章:

bash - awk 正在插入空格

linux - 搜索模式并删除所有行

linux - unix bash 查找具有 2 个显式文件扩展名的文件目录

configuration - 如何导出 WAS 6.1 服务器配置

bash - 文本文件中一行的非重复条目

linux 在一个文件中搜索多个单词

scripting - 在 FreeBSD 中运行脚本

bash - 如何检查传递给 shell 脚本的参数是否不是整数?

bash - 如何使用 sed 更改对目录的引用?

java - 将字符串从 Java 传递到 bash 脚本