I need to create a script to unbind/bind all usb in one linux machine.
我需要创建一个脚本来取消绑定/绑定所有USB在一台Linux机器上。
For this I need to run:
为此,我需要运行:
lsusb -t wich returns:
lsusb -t返回:
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:
为了通过创建脚本来实现这一点(我对linux很新),我做了以下事情:
#!/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.
我尝试了所有可能的组合以设置var。我总是得到一个错误。
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)
谢谢Ed Morton,输入是命令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
And I want to parse this information in order to get the BUS number and the port number. So the output should be:
我想解析这些信息以获取BUS号和端口号。所以输出应该是:
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!
2 个解决方案
#1
1
shell is an environment from which to call UNIX tools, with a language to sequence those calls.
shell是一个可以从中调用UNIX工具的环境,使用一种语言对这些调用进行排序。
grep is a UNIX tool to print lines from files (or pipes) that match regular expressions.
grep是一个UNIX工具,用于从与正则表达式匹配的文件(或管道)中打印行。
awk is the standard general-purpose UNIX tool for processing text.
awk是用于处理文本的标准通用UNIX工具。
They are 3 completely different tools with their own languages/syntax.
它们是3种完全不同的工具,具有自己的语言/语法。
You would call grep from shell to find a regexp and print the matching line.
您可以从shell调用grep来查找正则表达式并打印匹配的行。
You would call awk from shell to do more complicated text-manipulation operations which may or may not including anything that grep can do.
您可以从shell调用awk来执行更复杂的文本操作操作,这些操作可能包括也可能不包括grep可以执行的任何操作。
You would NOT call grep from awk and you CANNOT call awk from grep.
你不会从awk调用grep而你也不能从grep调用awk。
You can call shell from awk in some very rare situations where that is useful but you cannot call shell from grep.
你可以在一些非常罕见的情况下从awk调用shell,但是你不能从grep调用shell。
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.:
如果它有用,这里是一个awk脚本正确的awk语法,你可以用echo和grep等来做你正在做的事情:
$ 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:
请注意,如果你想要它转到几个文件以及stdout,那么你需要的只是代替后续的echo + pipe + tee:
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):
因为重复你已经处理的总线+端口组合的动作似乎没有意义(例如第二个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
}
}
}
#2
0
You can not define variable inside awk
你不能在awk中定义变量
var= $(echo $3 | grep -o "[1-9]"
Do some like this:
做一些这样的事情:
awk -v var=$(echo $3 | grep -o "[1-9]" '{print var}' file
PS I do not see why you need to use both awk
and grep
PS我不明白为什么你需要同时使用awk和grep
#1
1
shell is an environment from which to call UNIX tools, with a language to sequence those calls.
shell是一个可以从中调用UNIX工具的环境,使用一种语言对这些调用进行排序。
grep is a UNIX tool to print lines from files (or pipes) that match regular expressions.
grep是一个UNIX工具,用于从与正则表达式匹配的文件(或管道)中打印行。
awk is the standard general-purpose UNIX tool for processing text.
awk是用于处理文本的标准通用UNIX工具。
They are 3 completely different tools with their own languages/syntax.
它们是3种完全不同的工具,具有自己的语言/语法。
You would call grep from shell to find a regexp and print the matching line.
您可以从shell调用grep来查找正则表达式并打印匹配的行。
You would call awk from shell to do more complicated text-manipulation operations which may or may not including anything that grep can do.
您可以从shell调用awk来执行更复杂的文本操作操作,这些操作可能包括也可能不包括grep可以执行的任何操作。
You would NOT call grep from awk and you CANNOT call awk from grep.
你不会从awk调用grep而你也不能从grep调用awk。
You can call shell from awk in some very rare situations where that is useful but you cannot call shell from grep.
你可以在一些非常罕见的情况下从awk调用shell,但是你不能从grep调用shell。
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.:
如果它有用,这里是一个awk脚本正确的awk语法,你可以用echo和grep等来做你正在做的事情:
$ 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:
请注意,如果你想要它转到几个文件以及stdout,那么你需要的只是代替后续的echo + pipe + tee:
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):
因为重复你已经处理的总线+端口组合的动作似乎没有意义(例如第二个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
}
}
}
#2
0
You can not define variable inside awk
你不能在awk中定义变量
var= $(echo $3 | grep -o "[1-9]"
Do some like this:
做一些这样的事情:
awk -v var=$(echo $3 | grep -o "[1-9]" '{print var}' file
PS I do not see why you need to use both awk
and grep
PS我不明白为什么你需要同时使用awk和grep