![在灰壳中分割字符串? (忙碌盒)](https://linux22.com/image/138953/%E5%9C%A8%E7%81%B0%E5%A3%B3%E4%B8%AD%E5%88%86%E5%89%B2%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%9F%20%EF%BC%88%E5%BF%99%E7%A2%8C%E7%9B%92%EF%BC%89.png)
我正在尝试仅使用 BusyBox 中提供的工具在 ash shell 中拆分字符串。
该字符串的格式是host-name:port,host-name2:port2
,但我只关心第一个主机名和端口,我想将它们作为变量访问。
我尝试了在这里找到的一些选项,但大多数都与 bash 有关,并且 ash shell 中似乎不存在等效的命令/功能。
有任何想法吗?
答案1
除了具有许多副作用和限制的 IFS 解决方案之外,与 shell 无关的(对于许多 shell)解决方案可以正确处理空格、换行符、空字段和多个字符的除数,它是:
#!/bin/sh
in='One-XX-X-17.0.0'
a=$in; div='-'; set --
while
b=${a#*"$div"}
set -- "$@" "${a%%"$div"*}"
[ "$a" != "$b" ]
do
a=$b
done
printf 'Element: %s\n' "$@"
#split 17.0.0 into NUM
a=$4; div='.'; set --
while
b=${a#*"$div"}
set -- "$@" "${a%%"$div"*}"
[ "$a" != "$b" ]
do
a=$b
done
printf 'Num: %s\n' "$@"
将打印:
$ ./script
Element: One
Element: XX
Element: X
Element: 17.0.0
Num: 17
Num: 0
Num: 0
答案2
我用这个解决方案遇到了类似的问题(->将完整的字符串拆分为标记):
#!/bin/sh
input='host-name:port,host-name2:port2,One,XX X,192.178.88:999,17.0.0'
echo "input: $input"
OLDIFS=$IFS;IFS=,
for token in $input; do
hostname=$(echo ${token%:*})
port=$(echo ${token#*:})
echo "hostname: $hostname, port: $port"
done
IFS=$OLDIFS
结果是:
$ busybox ash bla.sh
input: host-name:port,host-name2:port2,One,XX X,192.178.88:999,17.0.0
hostname: host-name, port: port
hostname: host-name2, port: port2
hostname: One, port: One
hostname: XX X, port: XX X
hostname: 192.178.88, port: 999
hostname: 17.0.0, port: 17.0.0
要进一步阅读,您可以深入了解 ash 的手册页 (1) (https://linux.die.net/man/1/ash)并搜索“IFS”和“参数扩展”。
注意:仅当您信任输入时才执行此操作!请参阅下面有关文件通配和其他内容可能出错的问题的评论。如果您的输入受到某种控制,那么这是一个巧妙的解决方案。 (->我将它用于一个脚本,我知道在脚本的输入将被更改后,将立即进行测试,并且任何错误配置都会立即被注意到。[另外没有人将要曾经做*或那里的东西......呵呵著名的遗言])