在我可以解释这个问题之前,我必须对此进行一些澄清。
我正在为dd-wrt路由器更改vpn脚本。请注意,此路由器没有bash,因此我通过entware进行了安装,例如sed grep cut之类的所有命令,等等。
现在,我的脚本调用另一个脚本并从中收集数据。 调用脚本的输出是
./nordvpn-server-find -l fr
Looking for servers located in FR with current capacity lower than 30%...
fr27.nordvpn.com 9%
fr104.nordvpn.com 10%
fr169.nordvpn.com 10%
fr25.nordvpn.com 10%
fr37.nordvpn.com 10%
fr80.nordvpn.com 11%
fr98.nordvpn.com 11%
fr114.nordvpn.com 12%
fr127.nordvpn.com 13%
fr16.nordvpn.com 13%
fr133.nordvpn.com 14%
fr41.nordvpn.com 14%
fr50.nordvpn.com 14%
fr62.nordvpn.com 14%
fr67.nordvpn.com 14%
fr19.nordvpn.com 15%
fr30.nordvpn.com 15%
fr31.nordvpn.com 15%
fr46.nordvpn.com 15%
fr84.nordvpn.com 15%
如您所见,这是当前负载的服务器列表,该列表的格式为列,因此在我的脚本中,我使用此命令仅使用该列表的前3个服务器
declare -a SERVERDIRS # declare an array
SERVERDIRS+=($($COMMANDSPATH/bash $JFFSPATH/nordvpn-server-find -l it \
| $COMMANDSPATH/head -6 | $COMMANDSPATH/tail -3 | $COMMANDSPATH/awk '{print $1}'))
echo
echo ${SERVERDIRS[*]} # echo all the elements of the array
echo "number of element in array" ${#SERVERDIRS[@]}
echo "first element in array" ${SERVERDIRS[0]}
echo "last element in array" ${SERVERDIRS[${#SERVERDIRS[@]}-1]}
请注意,$ COMMANDSPATH和$ JFFSPATH是指向正确位置的路径变量。如您所见,如果我没记错,我将第一个3台服务器放入一个数组中,然后可以对其进行操作,这里是有关数组创建的输出
#vpn rnd
fr27.nordvpn.com fr104.nordvpn.com fr169.nordvpn.com
number of element in array 3
first element in array fr27.nordvpn.com
last element in array fr169.nordvpn.com
现在一切看起来不错,数组是3个元素,依此类推
所以我的期望是提取第一个“。”之前的所有数据。然后将其格式化为4位数字 fr27.nordvpn.com->必须成为-> fr0027,依此类推。
所以我尝试了这种方法 https://repl.it/@jorman/JovialAngryWebpages 在repl.it上确实有效,但我不知道为什么,在bash上不行! 查看此解决方案的输出
vpn rnd
first var
econd var 36
1
80
third var
irst var
econd var 36
1
129
third var
irst var
econd var 36
1
37
third var
似乎有一个奇怪的错误,首先缺少char“ irst”,所以我在调试模式下运行它,请参阅日志
+ declare -a SERVERDIRS
+ SERVERDIRS+=($($COMMANDSPATH/bash $JFFSPATH/nordvpn-server-find -l fr | $COMMANDSPATH/head -6 | $COMMANDSPATH/tail -3 | $COMMANDSPATH/awk '{print $1}'))
++ /opt/bin/head -6
++ /opt/bin/bash /jffs//nordvpn-server-find -l fr
++ /opt/bin/tail -3
++ /opt/bin/awk '{print $1}'
+ for i in "${SERVERDIRS[@]}"
++ /opt/bin/sed 's/\..*//'
++ echo 'fr188.nordvpn.com'
++ /opt/bin/cut -c1-2
+ aaa='
pt/bin/sed 's/\..*//'
++ echo 'fr188.nordvpn.com'
++ /opt/bin/grep -oP '\d+'
+ bbb='36
1
188'
++ printf %04d 36 1 188
+ bbbmod=003600010188
+ ccc='
cho 'first var
irst var
cho 'second var 36
1
188'
second var 36
1
188
+ echo 'third var
hird var
cho
+ for i in "${SERVERDIRS[@]}"
++ echo 'fr193.nordvpn.com'
++ /opt/bin/cut -c1-2
++ /opt/bin/sed 's/\..*//'
+ aaa='
pt/bin/sed 's/\..*//'
++ /opt/bin/grep -oP '\d+'
++ echo 'fr193.nordvpn.com'
+ bbb='36
1
193'
++ printf %04d 36 1 193
+ bbbmod=003600010193
+ ccc='
cho 'first var
irst var
cho 'second var 36
1
193'
second var 36
1
193
+ echo 'third var
hird var
cho
+ for i in "${SERVERDIRS[@]}"
++ echo 'fr194.nordvpn.com'
++ /opt/bin/sed 's/\..*//'
++ /opt/bin/cut -c1-2
+ aaa='
cho 'fr194.nordvpn.com'
++ /opt/bin/grep -oP '\d+'
++ /opt/bin/sed 's/\..*//'
+ bbb='36
1
194'
++ printf %04d 36 1 194
+ bbbmod=003600010194
+ ccc='
cho 'first var
irst var
cho 'second var 36
1
194'
second var 36
1
194
+ echo 'third var
hird var
cho
+ echo
+ echo 'fr188.nordvpn.com' 'fr193.nordvpn.com' 'fr194.nordvpn.com'
fr188.nordvpn.com fr193.nordvpn.com fr194.nordvpn.com
+ echo 'number of element in array' 3
number of element in array 3
+ echo 'first element in array' 'fr188.nordvpn.com'
first element in array fr188.nordvpn.com
+ echo 'last element in array' 'fr194.nordvpn.com'
last element in array fr194.nordvpn.com
+ echo
+ echo 'fr188.nordvpn.com'
+ /opt/bin/sed 's/\..*//'
+ /opt/bin/sed 's/[^0-9]*//g'
361188
+ exit
如果您发现3、6和1似乎来自代码
++ /opt/bin/head -6
++ /opt/bin/bash /jffs//nordvpn-server-find -l fr
++ /opt/bin/tail -3
++ /opt/bin/awk '{print $1}'
我无法解释发生了什么事。
我想念一些代码吗?有一种更好的方法可以从数组中提取信息,我需要数组吗?
非常感谢能够阅读所有这些内容,并感谢所有会提出一些想法的人。
乔
答案 0 :(得分:0)
这可能有效(如果我正确理解了您想要实现的目标)。
echo "
Looking for servers located in FR with current capacity lower than 30%...
fr27.nordvpn.com 9%
fr104.nordvpn.com 10%
fr169.nordvpn.com 10%
fr25.nordvpn.com 10%
fr37.nordvpn.com 10%
fr80.nordvpn.com 11%
fr98.nordvpn.com 11%
fr114.nordvpn.com 12%
fr127.nordvpn.com 13%
fr16.nordvpn.com 13%
fr133.nordvpn.com 14%
fr41.nordvpn.com 14%
fr50.nordvpn.com 14%
fr62.nordvpn.com 14%
fr67.nordvpn.com 14%
fr19.nordvpn.com 15%
fr30.nordvpn.com 15%
fr31.nordvpn.com 15%
fr46.nordvpn.com 15%
fr84.nordvpn.com 15%
" | awk 'BEGIN { counter=0; } /nordvpn.com/ { split($1, a, /\./); print a[1]; counter++; if ( counter == 3 ) exit; }'
fr27
fr104
fr169
很明显,在您的情况下,您不应使用echo
,而应直接使用脚本的输出。
答案 1 :(得分:0)
您的问题尚不清楚,因此让我们从清理您的Shell脚本开始,看看我们要去哪里。鉴于此输入:
$ cat file
Looking for servers located in FR with current capacity lower than 30%...
fr27.nordvpn.com 9%
fr104.nordvpn.com 10%
fr169.nordvpn.com 10%
fr25.nordvpn.com 10%
fr37.nordvpn.com 10%
fr80.nordvpn.com 11%
fr98.nordvpn.com 11%
fr114.nordvpn.com 12%
fr127.nordvpn.com 13%
fr16.nordvpn.com 13%
fr133.nordvpn.com 14%
fr41.nordvpn.com 14%
fr50.nordvpn.com 14%
fr62.nordvpn.com 14%
fr67.nordvpn.com 14%
fr19.nordvpn.com 15%
fr30.nordvpn.com 15%
fr31.nordvpn.com 15%
fr46.nordvpn.com 15%
fr84.nordvpn.com 15%
然后执行当前正在执行的脚本操作,应这样写:
$ cat tst.sh
serverDirs=( $(
cat file |
awk 'NR>3{print $1} NR==6{exit}'
) )
printf '\n'
printf '%s\n' "${serverDirs[*]}" # print all the elements of the array
printf 'number of element in array %s\n' "${#serverDirs[@]}"
printf 'first element in array %s\n' "${serverDirs[0]}"
printf 'last element in array %s\n' "${serverDirs[${#serverDirs[@]}-1]}"
$
$ ./tst.sh
fr27.nordvpn.com fr104.nordvpn.com fr169.nordvpn.com
number of element in array 3
first element in array fr27.nordvpn.com
last element in array fr169.nordvpn.com
很明显,我用cat file
代替了$COMMANDSPATH/bash $JFFSPATH/nordvpn-server-find -l it
,因为我将其余脚本的输入保存在file
中,而我没有nordvpn-server-find
而且我没有为awk命令加上$COMMANDSPATH/
前缀,因为我没有设置该变量。
除此之外-使用awk时不需要头+尾加管道,不要为非导出变量名使用所有大写字母,以免与导出变量冲突,printf比echo更可移植,并且除非您有特定目的,否则必须始终引用Shell变量。所以,我已经照顾了所有这些。
现在,您还需要什么?我没有在您的问题中看到预期的输出,而我所看到的暗示预期的输出可能是So my expectation is to extract all the data before the very first "." and then format it to have it with 4 digits, for example fr27.nordvpn.com -> have to became -> fr0027 and so on.
-如果仅此而已,那么我们只需更改awk脚本即可:>
$ cat tst.sh
serverDirs=( $(
cat file |
awk '
NR>3 {
alpha = num = rest = $1
sub(/[0-9].*/,"",alpha)
gsub(/^[^0-9]+|\..*/,"",num)
sub(/^[^.]+/,"",rest)
num = sprintf("%04d",num)
print alpha num rest
}
NR==6 { exit }
'
) )
printf '\n'
printf '%s\n' "${serverDirs[*]}" # print all the elements of the array
printf 'number of element in array %s\n' "${#serverDirs[@]}"
printf 'first element in array %s\n' "${serverDirs[0]}"
printf 'last element in array %s\n' "${serverDirs[${#serverDirs[@]}-1]}"
$
$ ./tst.sh
fr0027.nordvpn.com fr0104.nordvpn.com fr0169.nordvpn.com
number of element in array 3
first element in array fr0027.nordvpn.com
last element in array fr0169.nordvpn.com
那是你想做什么?
答案 2 :(得分:0)
首先,我想让所有对此做出回应的人加入坦克! 我读了一些好的代码,将在这个小脚本中实现。
但是我发现了问题: 查看日志和调试,我看到这样的代码
[\033
在我的脑海中,我确定自己已经看过了!
返回服务器的nordvpn脚本加载,并用tput写入输出,因此输出是彩色的!碰巧所有这些信息都跳入了代码中,并且当所有逻辑切掉grep并解析所有信息时,“颜色代码”仍然存在并且有所作为!
所以我禁用了彩色输出,所有的工作都像是一个吊饰!
许多战车为您提供时间和帮助,就像往常一样