我正在尝试采用这样的值:
test2.sh switchname unicast [IgnorePort]
IgnorePort
下方有范围,例如1-8,12,34,37-43
或类似的任何变化。我将如何处理这种解析为数组或单个值的解析
我一直在搜索它,却找不到任何东西,尽管我觉得这是每个人在某个时间点都必须学习的东西。
test2.sh switchname unicast 1
test2.sh switchname unicast 2
test2.sh switchname unicast 3
test2.sh switchname unicast 10
test2.sh switchname unicast 1-3,10
答案 0 :(得分:2)
要将该范围的数字转换为列表,请尝试:
awk -F- -v RS=, '{print $1} NF==2{for (i=$1+1;i<=$2;i++)print i}'
例如:
$ echo 1-3,5,9-10 | awk -F- -v RS=, '{print $1} NF==2{for (i=$1+1;i<=$2;i++)print i}'
1
2
3
5
9
10
或者,要在脚本中使用:
$ cat script
#!/bin/bash
for i in $(echo "$3" | awk -F- -v RS=, '{print $1} NF==2{for (i=$1+1;i<=$2;i++)print i}')
do
echo "Working on $i"
done
作为运行上述脚本的示例:
$ bash script switchname unicast 1-2,11,20-21
Working on 1
Working on 2
Working on 11
Working on 20
Working on 21
awk一次读取一条记录。每个记录都分为几个字段。在我们的例子中,我们将,
视为记录分隔符。因此,例如在读入1-3,5,9-10
时,awk看到的第一个记录为1-3
,并且该记录具有两个字段1
和3
。第二个记录是5
,依此类推。每条记录依次处理。
-F-
这告诉awk使用-
作为字段分隔符
-v RS=,
这告诉awk使用,
作为记录分隔符。
print $1
这告诉awk打印第一个字段。
NF==2{for (i=$1+1;i<=$2;i++)print i}
如果记录中有两个字段,则打印其余数字。
答案 1 :(得分:0)
最简单的方法是接受单个数字列表,而不是您必须解析的范围。 bash
可以通过括号扩展轻松地为您生成单个数字。
#! /bin/bash
# Sketch of your script test2.sh when accepting arbitrary many individual numbers
switchname="$1"
unicast="$2"
shift 2
ports=("$@")
# do something, for instance ...
for port in "${ports[@]}"; do
# something
done
然后按如下所示调用您的脚本以模拟范围1-8,12,34,37-43
test2.sh switchname unicast {{1..8},12,34,{37..43}}
如果您真的想指定范围,那么下一个更简单的操作就是将范围转换为大括号模式,然后eval
将其转换为大括号模式。请记住,如果您弄乱了输入验证,可能会导致代码注入。
#! /bin/bash
# Sketch of your script test2.sh when accepting one range
switchname="$1"
unicast="$2"
range="$3"
if ! [[ range =~ ^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$ ]]; then
echo "Illegal range expression: $range"
exit 1
fi
bracePattern="{$(sed -E 's/([^,]+)-([^,]+)/{\1..\2}/g' <<< "$range")}"
eval "ports=($bracePattern)"
# do something, just like in the first version of the script
答案 2 :(得分:0)
以下功能将回显范围内的每个数字
function ranger {
A=$(echo $1 | tr "," " ")
for a in $A
do
if [[ $a == *"-"* ]]; then
B=( $(echo $a | tr "-" " ") )
x=${B[0]}
y=${B[1]}
for z in $(seq ${B[0]} ${B[1]})
do
echo $z
done
else
echo $a
fi
done
}
因此,修改test2.sh与此类似
function test2 {
for i in $(ranger $3)
do
#execute test2.sh code
done
}
然后运行
$ test2.sh switchname unicast 1,2,5-7