One option could be to use system() directly from within awk:
1. Validate
Validate by requesting device from lsusb:
lsusb | awk '/Tascam.*Hub$/{ system("lsusb -d " $6) }'
That would take vendor:product, (field 6), from whole lines matching:
Tascam<Anything zero or more times>Hub<END-OF-LINE>
and execute: lsusb -d vendor:product
This would execute on all matching Tascam hubs.
2. Real call
Actually call usbreset:
lsusb | sudo awk '/Tascam.*Hub$/{ system("/usr/bin/usbreset " $6) }'
Or perhaps better, exit if error:
lsusb | sudo awk '/Tascam.*Hub/{ if (system("/usr/bin/usbreset " $6)) exit 1 }'
As system(expression) return exit status of the command, and 0 is success, one can use if () to check as if status is <> 0 it would proceed with exit 1. Exit with something else then 0 to signal error.
Optionally use != 0 if you find that easier to read. And perhaps throw in an error.
lsusb | sudo awk '
/Tascam.*Hub/ {
if (system("/usr/bin/usbreset " $6) != 0) {
print "usbreset failed" >"/dev/stderr"
exit 1
}
}'
3. Wrapper + filter on Device
If you want to filter by device-number, it would likely be best to wrap it in a shell-script (which you likely would anyhow), and then do something like:
#! /bin/sh -
Check argument is given
if [ -z "$1" ]; then
printf 'Missing device number\n' >&2
exit 1
fi
Check sudo or abort
sudo echo >/dev/null || exit 1
lsusb |
sudo awk -v dev="$1" '
BEGIN {
dev = sprintf("%03d:", dev)
eno = 1
}
$4 == dev && /Tascam.*Hub/ {
if (system("/usr/bin/usbreset " $6) != 0) {
eno = 2
} else {
eno = 0
}
# Exit on first match of device-number + name
exit
}
END {
if (eno == 0)
print "OK"
else if (eno == 1)
print "No device found" >"/dev/stderr"
else if (eno == 2)
print "usbreset failed" >"/dev/stderr"
exit eno
}'
Note on usbreset
Not able to install it locally, but looks like some take argument as:
/dev/bus/usb/<bus>/<device-number>
In that case you might need to use something like:
# Testing:
system(sprintf("ls -l /dev/bus/usb/%03d/%03d", $2, $4))
Testing:
system(sprintf("/usr/bin/usbreset /dev/bus/usb/%03d/%03d", $2, $4))
4. Note on things in question:
grep when awk is next up is an unnecessary step. awk matches regular expressions – and it in this case it is a simple string (in your code).
awk '/^foo/{ this line starts with foo }' etc.
printf $6 "\n"
Looks like you want to print $6 + line-feed. That would be either of:
print $6
printf "%s\n", $6
It also tells awk to use $6 as format string. This can go bad, and is in general not a good thing to do. If $6 was for example foo%dbar, awk would expect a digit as arameter. etc.
printf "/usr/bin/usbreset %d", $6, say "print digit" and here value is "$6". As field six is hex:hex the printf statement will only print the first digits, if any, else zero.
12a1:06df -> 12
a112:3619 -> 0
lsusb | grep "Tascam" | awk '{printf "/usr/bin/usbreset %d", $6}'– Beaker Jul 02 '21 at 01:17usbresettake an arbitrary number of device IDs? I.e.usbreset ID1 ID2 ID3 ...or only one at a time? – ibuprofen Jul 02 '21 at 03:07