我有一个bash脚本,我使用for
循环生成一个数字列表(增加一个)。
在我的循环中,我将echo
与tee
结合使用来构建我的字符串。
然后我使用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
的内容吗?
答案 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"
但这不能参数化。