我有一个脚本,我想在其中使用命令列出 USB 设备lsblk
。
命令:
$ lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb
这导致
sdb usb Kingston DataTraveler 2.0
sdc usb Kingston DT 101 G2
我想将结果保存在一个变量中以便以后工作,所以我写
$ usbs=$(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb)
我所期望的是变量usbs
将结果存储在上面的两行中。但是如果我运行:
for i in ${usbs[@]}; do
echo $i
done
我把结果分成几个词:
sdb
usb
Kingston
DataTraveler
2.0
sdc
usb
Kingston
DT
101
G2
问题:
有没有一种方法可以使用该grep
命令将命令的结果存储为整行两行?
我更愿意知道是否有一个简单的解决方案,而不是将结果转储到文件中然后读取它。
这是使用readarray/mapfile的好情况:
这将使用您的输出创建一个数组,其中每一行都分隔成它自己的元素。
在您的情况下,它将创建一个数组,例如:
正如您将整个输出分配给一个变量(不是数组)一样,它本质上是这样做的:
为了使它成为一个数组,你会这样做:
但这会使每个由空格分隔的单词成为自己的元素,相当于:
正如几位评论者所指出的,并且通常始终是最佳实践,应引用变量。在这种情况下,您必须并且通常应该始终引用您的变量。
在 的情况下
for i in ${usbs[@]}; do
,i
将设置为 中的每个单词(由空格分隔)usbs
。如果您像 一样引用它for i in "${usbs[@]}"; do
,那么i
将根据需要设置为 的每个元素usbs
。这主要是新行和 bash 变量的欺骗,尽管这不包括数组。从那里,要使用包含多行的变量,您需要在换行符处进行参数扩展拆分并跳过通配符,并根据您的数据可能避免其他修改:
Jesse_b 建议的数组
readarray/mapfile
是最简单的,因为它已经在行处分割。但是您可以像上面那样“手动”完成它:是的,您的分配代码是正确的:
这完全符合要求;在单个变量(不是数组)中,它存储两行,
lsblk
以换行符分隔。但是for
循环不是读取该变量的正确工具。while
循环要好得多,这是一个虚构数据的示例,因为某些阅读器可能没有插入任何 USB 设备:输出:
这是一个更短的方法:
注意:虽然普通的POSIX样式变量
x
不是数组,但bash
允许x
使用数组表示法进行识别,并且不会抱怨x
不是数组。演示:输出:
但
x
不是数组。如果是,这段代码(使用bash
参数转换 符号运算符)肯定会输出一个数组:A
...它没有:
相比之下,让我们将上面的内容与如果它是一个数组的样子进行比较。首先制作一个非常相似的数组
y
,然后使用符号运算符来显示差异:A
输出: