在搜索了不同解决方案的数小时后,我还没有找到一个可行的解决方案。 Bash和Shell Scripting不是我最强的领域。
我有一个变量,它有行(新行)和列(制表符分隔)。我想要做的是循环遍历行并获取'列X'然后将该项放入变量中,以便我可以对该单元格执行某些操作。即例如回声。
行数未知,但已知列数,因此可以始终以列3为例。
我在Linux上运行Bash v.4。
示例输入(无法在这里找到实际'标签'事物的方法吗?);
UniqueID1 -tab- Description -tab- FriendlyNameABC
UniqueID1 -tab- Description -tab- FriendlyNameXYZ
示例输出将循环遍历列表,获取FriendlyNameABC(col 3)并将其回显。
我正在尝试在此处展开此脚本,https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=77277&p=1178478#p1178478 - 这是一个通过WPS连接到WiFi的shell脚本。该页面上提供的脚本(下面仅供参考)有效,但它依赖于仅选择最强的WiFi信号,这并不总是您要连接的网络。
#!/bin/bash
# only run if there's no current wifi connection
if ! ifconfig wlan0 | grep -q "inet addr:" ; then
# grab AP's that support WPS, sort by strength and select the strongest
wpa_cli scan_results | grep WPS | sort -r -k3 | awk 'END{print $NF}' >/tmp/wifi
read ssid < /tmp/wifi
wpa_cli wps-pbc $ssid
fi
目前,我已设法修改上面的脚本,以便以'wpa_cli ..'开头的行现在读取如下,这将整个标识的WiFi网络放在一个变量中,但后来我很难分裂全力以赴。
wpa_cli scan_results | grep WPS | sort -r -k3 $allConnections
本质上,上面的代码我需要翻译成这个伪代码;
#!/bin/bash
# only run if there's no current wifi connection
if ! ifconfig wlan0 | grep -q "inet addr:" ; then
# grab AP's that support WPS, sort by strength and select the strongest
wpa_cli scan_results | grep WPS | sort -r -k3 | awk 'END{print $NF}' >/tmp/wifi
read ssid < /tmp/wifi
#This is the section below that I'm struggling to implement (this is pseudo code, the only bit of working code is the line starting with wpa_cli...)
while(ssid.hasNext(){
#Try connecting to the network
wpa_cli wps-pbc $ssid
if(successful){break();}
}
fi
我应该补充一下,我假设数据是制表符,并根据我运行命令时布局的外观划分新行;
wpa_cli scan_results
在Linux命令行运行命令时,有没有办法确认分隔符?
答案 0 :(得分:1)
如果您的“每个单元格”逻辑足够简单,您可以执行以下操作:
echo $VARIABLE | cut -f3 -d$'\t' | xargs echo
# echo $VARIABLE | # pipe the value of VARIABLE to the next statement...
# cut -f3 -d$'\t' | # take the 3rd column, using tabs for the delimiters
# xargs echo # for each resulting row, call `echo` with that row as the argument
如果你需要做一些更复杂的事情:
for CELL in $(echo $VARIABLE | cut -f3 -d$'\t'); do # for each line in the result of this command...
echo $CELL
# Other stuff with $CELL
done
答案 1 :(得分:0)
简单永远胜利。我设法解决了这个问题。人们评论的帮助,谢谢,这有助于我在测试各种脚本时澄清一些事情。
在对所有内容进行测试后,显而易见的是数据被破坏的方式并不完全正确。空格被视为选项卡,这意味着您要连接的SSID网络名称,当它应该是“我的网络”时,它将简称为“网络”,然后由于没有网络称为“网络”网络”。因此,在删除几乎所有代码并简化操作之后,我记得以前测试过你实际上并不需要提供网络名称,你可以简单地运行命令而不需要任何更智能的逻辑,这简化了一切。
#!/bin/bash
# only run if there's no current wifi connection
if ! ifconfig wlan0 | grep -q "inet addr:" ; then
wpa_cli wps-pbc
fi
您将在上面注意到,此脚本只是监听正在按下的WPS按钮并自动连接到该网络。无论这是最强的信号,还是天气,这个网络名称都有空格。
答案 2 :(得分:0)
首先花一点时间考虑echo $a
和echo "$a"
之间的区别
在第一种情况下,a
的值作为单独的字段赋予echo
,在第二种情况下作为1字段。因此,在第一种情况下bash
将更改标签和换行符,删除可能位于$a
中的所有行和列。
将a
填充为4行的一种棘手方法是在格式化字符串中提供printf
个更多参数:
a=$(printf "%s\t%s\t%s\n" 1 a A 2 b B 3 c C 4 "F o u r" "4 4 4 4" )
在printf
之后,echo
可能会让您大吃一惊:
you> echo $a | sed -r 's/\t/<tab>/g'
1 a A 2 b B 3 c C 4 F o u r 4 4 4 4
you> echo "$a" | sed -r 's/\t/<tab>/g'
1<tab>a<tab>A
2<tab>b<tab>B
3<tab>c<tab>C
4<tab>F o u r<tab>4 4 4 4
您可以从a的calue创建一个循环,将每个字段分配给另一个变量,此示例切换字段:
you> while IFS=$'\t' read -r id desc friend; do
echo "$id = ${friend} (${desc})"
done <<< "$a"
1 = A (a)
2 = B (b)
3 = C (c)
4 = 4 4 4 4 (F o u r)
我不懂行
wpa_cli scan_results | grep WPS | sort -r -k3 $allConnections
如果要对grep结果进行排序,则应删除$allConnections
(或为空)。当var allConnections
填充文件名时,您可以使用> $allConnections
(重定向到文件),但我认为您希望将结果存储在var中。
allConnections = $(wpa_cli scan_results | grep WPS | sort -r -k3)
现在你可以做类似
while IFS=$'\t' read -r id desc friend; do
echo "Trying ssid ${id} = ${friend} (${desc})"
wpa_cli wps-pbc ${id} && break
done <<< "$allConnections"
&& break
假设wpa_cli
成功时返回0。