【问题标题】:variable is a substring of variable bash变量是变量 bash 的子字符串
【发布时间】:2014-05-17 22:00:55
【问题描述】:

我正在尝试查看用户输入的输入是否包含在以空格分隔的列表中。

interfaces=`ls /sys/class/net | awk '{ ORS=" "; print; }'`
# Loop until valid input for interface is received
while [[ -z "$interface" || ! "$interfaces" =~ "$interface" ]]
do
    echo -n "Select the interface ( "$interfaces"): "
    read interface
done

$interfaces 可能包含类似于"eth0 lo wlan0 wlan1 " 的内容,我正在尝试查看用户是否输入了该列表中的接口,如果没有告诉他们再做一次。

我似乎无法弄清楚如何做到这一点。我尝试使用通配符和== 运算符以及与=~ 匹配的正则表达式,但运气不佳。

是否有一种简单而干净的方法来检查用户输入的值是否在我创建的列表/字符串中?

感谢您的帮助!

【问题讨论】:

  • 您在当前版本中遇到的问题是什么?
  • @thatotherguy 根据我是使用通配符还是正则表达式,一旦输入有效输入,它就永远不会退出循环,或者无论输入什么输入它都会退出循环。目前使用此代码 sn-p 无论输入如何,它都会退出。
  • 确保您正在测试您发布的代码,而不是其他版本或更大的脚本,这是其中的一部分。它对我有用,并一直询问直到我输入 $interfaces 的子字符串。
  • 仅供参考——见mywiki.wooledge.org/ParsingLs;以编程方式使用ls 绝不是好的做法。 interfaces=( /sys/class/net/* ); interfaces=( "${interfaces[@]##*/}" ) 是获取接口名称数组的更好方法。 (请注意,作为实际数组而不是空格分隔的字符串,扩展它的过程有点不同)
  • ...或:interfaces=( /sys/class/net/* ); if [[ " ${interfaces[*]} " =~ " $foo " ]]; then ...,如果您想坚持使用字符串比较来确定成员资格。

标签: regex linux string bash


【解决方案1】:

更新,感谢@thatotherguy 和@rici 的反馈: 修改后,我意识到我对引用=~右侧的表达式有误解 - 见底部:

问题中的命令应该有效,但它会将用户输入与列表的任何部分相匹配;这是一个将用户输入与整个列表条目相匹配的版本:

 while [[ -z $interface || ! " $interfaces " =~ " $interface " ]]

(顺便说一句:您可以考虑使用bashselect 命令而不是while 循环,其中为用户提供编号选择并键入所需的数字 执行选择。)


=~ 右侧重新引用(适用于bash 3.2 或更高版本):

  • 任何引用部分都被视为文字
  • 未引用部分被视为正则表达式(即,.*、...等字符具有特殊含义)

如果整个右侧被引用 - 如上面的解决方案 - =~ 有效地执行文字子字符串匹配

【讨论】:

  • 如何修改条件的右侧,使其匹配整个单词。目前,如果我输入“oii”,它确实会要求另一个输入,但如果我输入“a”,它会退出,我认为这是因为它与包含"eth0 lo wlan0 wlan1 " 的列表中的 wlan0 匹配。如果你输入“l”可以看到同样的效果,但如果你输入“llll”,它会要求一个新的输入。
  • 在这种情况下,为什么要将$interface 视为正则表达式而不是文字字符串?
  • 补充@thatotherguy 所说的内容,如果您不引用$interface 并且用户键入.* 之类的内容,那么正则表达式匹配将产生不希望的结果。不过,对于空白解决方案 +1。
  • @rici 也很重要;希望我的更新答案现在是正确的解决方案。
  • 支持这个关于 bash 的精彩讲座。 :)
猜你喜欢
  • 2018-11-22
  • 1970-01-01
  • 2018-09-23
  • 2017-06-21
  • 2020-08-14
  • 2013-07-15
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
相关资源
最近更新 更多