I need to create a script to unbind/bind all usb in one linux machine.
For this I need to run:
lsusb -t wich returns:
root@lsdg7sd-fc:~# lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/10p, 12M
|__ Port 4: Dev 2, If 0, Class=vend., Driver=ftdi_sio, 12M
|__ Port 6: Dev 4, If 0, Class=HID, Driver=usbhid, 1.5M
|__ Port 6: Dev 4, If 1, Class=HID, Driver=usbhid, 1.5M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/10p, 480M
Now, for this example I need to run:
// disable the bus 1, port 1
echo '2-4' | tee /sys/bus/usb/drivers/usb/unbind
// disable the bus 1, port 2
echo '2-6' | tee /sys/bus/usb/drivers/usb/unbind
// enable the bus 1, port 1
echo '2-4' | tee /sys/bus/usb/drivers/usb/bind
// enable the bus 1, port 2
echo '2-6' | tee /sys/bus/usb/drivers/usb/bind
In order to achieve this by creating a script (I am very new to linux), I did the following:
#!/bin/bash
lsusb -t | awk '{
bus="";
if($1=="|__")
print "Child USB Port: ",$3;
else if ($1=="/:") {
print $3;
var= $(echo $3 | grep -o "[1-9]");
echo $var;
}
}'
var=`echo "02.Port" | grep -o "[1-9]"`;
echo $var;
var=`echo "02.Port" | grep -o "[0-9]\{2\}"`;
echo $var;
I tried all the possible combinations in order to set var. I always get an error.
awk: line 8: syntax error at or near grep
Can anyone suggest a solution or another approach?
Thanks for reading.
---------------------- Update
Thanks Ed Morton, the input is the result of the command lsusb -t: (at my end)
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/10p, 12M
|__ Port 4: Dev 2, If 0, Class=vend., Driver=ftdi_sio, 12M
|__ Port 6: Dev 4, If 0, Class=HID, Driver=usbhid, 1.5M
|__ Port 6: Dev 4, If 1, Class=HID, Driver=usbhid, 1.5M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/10p, 480M
And I want to parse this information in order to get the BUS number and the port number. So the output should be:
2-1
2-4
2-6
2-6
1-1
But, I only need the "child" ports, so I need the following output:
2-4
2-6
2-6
Thanks again!
shell is an environment from which to call UNIX tools, with a language to sequence those calls.
grep is a UNIX tool to print lines from files (or pipes) that match regular expressions.
awk is the standard general-purpose UNIX tool for processing text.
They are 3 completely different tools with their own languages/syntax.
You would call grep from shell to find a regexp and print the matching line.
You would call awk from shell to do more complicated text-manipulation operations which may or may not including anything that grep can do.
You would NOT call grep from awk and you CANNOT call awk from grep.
You can call shell from awk in some very rare situations where that is useful but you cannot call shell from grep.
You posted some sample input in your question, now update it to show the specific output you would like to get as a result of running a tool on that input so we can help you write the tool to do that.
In case it's useful, here is the correct awk syntax for an awk script to do what you are trying to do with echo and grep, etc.:
$ cat tst.awk
{
if (/\|__/) {
print "Child USB Port: ",$3
}
else {
print $3
var = $3
gsub(/[^[:digit:]]/,"",var)
print var
}
}
$
$ awk -f tst.awk file
02.Port
02
Child USB Port: 4:
Child USB Port: 6:
Child USB Port: 6:
01.Port
01
Given your updated question:
$ cat tst.awk
{
var = $3+0
if (/\/:/) {
bus = var
}
else {
print bus "-" var
}
}
$
$ awk -f tst.awk file
2-4
2-6
2-6
Note that if you want that to go to a couple of files as well as stdout then all you need instead of a subsequent echo+pipe+tee is:
BEGIN{
path = "/sys/bus/usb/drivers/usb/"
unbind = path "unbind"
bind = path "bind"
}
{
var = $3+0
if (/\/:/) {
bus = var
}
else {
busPort = bus "-" var
print busPort
print busPort > unbind
print busPort > bind
}
}
and since it seems pointless to repeat the action for bus+port combinations you've already processed (e.g. the second 2-6):
BEGIN{
path = "/sys/bus/usb/drivers/usb/"
unbind = path "unbind"
bind = path "bind"
}
{
var = $3+0
if (/\/:/) {
bus = var
}
else {
busPort = bus "-" var
if (!seen[busPort]++) {
print busPort
print busPort > unbind
print busPort > bind
}
}
}