Array assignment syntax in zsh, ksh93, bash, mksh or yash is:
array=( value1 value2... )
Getting the output of a command is $(a command)
.
Splitting the output of a command on newline can be done with the f
parameter expansion flag in zsh
or in other shells by leaving that $(...)
unquoted (the split+glob operator), after having assigned the newline character to the $IFS
special variable and disabled globbing.
zsh
:
array=( ${(f)"$(a command)"} )
other shells (but also zsh)
IFS='
'
set -o noglob # not needed in zsh unless in sh/ksh emulation
array=( $(a command) )
To get the 6th blank delimited field of each of the lines of the output of a command, as others have said, you can use awk '{print $6}'
or grep -Po '^.*?ID \K.{9}'
(assuming GNU grep
or compatible with perl-style regex support enabled) to get the nine characters after the first occurrence of ID<space>
as you requested. So putting it altogether, that becomes:
array=( ${(f)"$(lsusb | awk '{print $6}')" ) # (zsh)
IFS='
'
set -o noglob
array=( $(lsusb | awk '{print $6}') )
Now, the default value of $IFS
is space, tab, newline (and NUL in zsh), and USB ids in theory only contain hexadecimal digits and colons, so the output of awk
should be guaranteed not to contain space, tab, nul nor glob characters, so if you can guarantee that $IFS
still contains its default value, you can omit the first two commands and simplify it to:
array=( $(lsusb | awk '{print $6}') )
Or you could get the information directly from /sys
without need for the lsusb
nor awk
command in zsh
with:
array=(
/sys/bus/usb/devices/*/idVendor(Ne['REPLY=$(<$REPLY):$(<$REPLY:h/idProduct)'])
)
Using globbing to find the idVendor
files and the e
glob qualifier to replace each glob expansion with the contents of that file and that of the idProduct
file in the same directory (also has the benefit of giving you a sorted list).