如何迭代for循环并创建自定义字符串

时间:2017-05-05 13:15:34

标签: bash shell unix for-loop

我有一个bash脚本,我使用for循环生成一个数字列表(增加一个)。

在我的循环中,我将echotee结合使用来构建我的字符串。

然后我使用sed来获取我的"列表" (作为文件输入)数字,然后格式化。

由于我使用for循环来生成此列表(文本文件),是否有更好,更有效的方式来创建我的字符串(它被附加为' s循环)包括双引号值,而不必先写入文件?

这是我的代码:

#!/usr/local/bin/bash

if [[ $# != 3 ]]; then
   echo "Usage:   ./crIPRange.sh <octet> <start#> <ending#>" 2>&1
   echo "Example: ./crIPRange.sh 10.1.2 100 150" 2>&1
   exit 1
fi

_octet="$1"
_startIP="$2"
_IPList="List1.out"
_IPListFinal="List2.out"

for (( c=$2; c<=$3; c++ ))
do
  echo "${_octet}.$c" | tee >> ${_IPList}
  sed -E 's/^(.*)$/"\1"/' ${_IPList} | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g' |  tee > ${_IPListFinal}
done

换句话说,我认为我不一定需要将其作为列表写入文件的步骤?

所以最后,我有(2)输出文件,我真的只需要我的最终输出。我会使用类似printf的内容吗?

1 个答案:

答案 0 :(得分:1)

这看起来像是一个以逗号分隔列表的残酷复杂方式。对于每个条目,您的sed命令都会遍历完整文件,只是用逗号替换单个换行符。将sed移动到循环外部并仅执行一次就可以提高效率。

但你根本不需要sed(也没有中间文件)。此解决方案使用我们想要的元素填充数组,然后将其打印为单个字符串,并将IFS设置为逗号:

#!/bin/bash

(( $# != 3 )) && echo "Wrong number of arguments" >&2

subnet=$1
from=$2
to=$3

for (( i = from; i <= to; ++i )); do
    arr+=("\"$subnet.$i\"")
done

IFS=,

echo "${arr[*]}"

请注意,您的比较if [[ $# != 3 ]]使用!=表示字符串,但应使用-ne表示数字。或者更简单,(( ))就是这样做的。

用法和输出:

$ ./octet 1.2.3 10 15
"1.2.3.10","1.2.3.11","1.2.3.12","1.2.3.13","1.2.3.14","1.2.3.15"

或者,如果你不想要一个功能,你可以使用大括号展开和tr

$ echo \"1.2.3.{10..15}\" | tr ' ' ,
"1.2.3.10","1.2.3.11","1.2.3.12","1.2.3.13","1.2.3.14","1.2.3.15"

但这不能参数化。