Linux AWK错误-grep处或附近的语法错误

Linux AWK错误-grep处或附近的语法错误,linux,bash,awk,usb,lsusb,Linux,Bash,Awk,Usb,Lsusb,我需要创建一个脚本,在一台linux机器上解除绑定/绑定所有usb 为此,我需要运行: // 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

我需要创建一个脚本,在一台linux机器上解除绑定/绑定所有usb

为此,我需要运行:

 // 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
lsusb-t wich返回:

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
现在,对于这个示例,我需要运行:

 // 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
为了通过创建脚本实现这一点(我对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;
为了设置变量,我尝试了所有可能的组合。我总是得到一个错误

awk: line 8: syntax error at or near grep
有人能提出解决方案或其他方法吗

谢谢你的阅读

----------------------更新

感谢Ed Morton,输入是命令lsusb-t的结果:(在我这边)

我想解析这些信息,以便得到总线号和端口号。因此,输出应为:

2-1
2-4
2-6
2-6
1-1
但是,我只需要“子”端口,因此我需要以下输出:

2-4
2-6
2-6

再次感谢

您不能在
awk

var= $(echo $3 | grep -o "[1-9]"
这样做:

awk -v var=$(echo $3 | grep -o "[1-9]" '{print var}' file

PS我不明白为什么您需要同时使用
awk
grep

shell是一个调用UNIX工具的环境,它使用一种语言来对这些调用进行排序

grep是一个UNIX工具,用于打印与正则表达式匹配的文件(或管道)中的行

awk是处理文本的标准通用UNIX工具

它们是3种完全不同的工具,具有各自的语言/语法

您可以从shell调用grep来查找regexp并打印匹配行

您可以从shell调用awk来执行更复杂的文本操作,这些操作可能包括也可能不包括grep可以执行的任何操作

您不能从awk调用grep,也不能从grep调用awk

在一些非常罕见的情况下,您可以从awk调用shell,这非常有用,但您不能从grep调用shell

您在问题中发布了一些示例输入,现在对其进行更新,以显示在该输入上运行工具后希望获得的特定输出,以便我们可以帮助您编写工具来实现这一点

如果有用的话,下面是一个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
鉴于你的最新问题:

$ cat tst.awk
{
    var = $3+0
    if (/\/:/) {
        bus = var
    }
    else {
        print bus "-" var
    }
}
$
$ awk -f tst.awk file
2-4
2-6
2-6
请注意,如果您想将其转到几个文件以及标准输出,那么您需要的不是后续的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
    }
}
由于对已经处理的总线+端口组合(例如,第二个2-6端口)重复该操作似乎毫无意义:


这里有awk与shell脚本的混淆。几乎所有的“awk脚本”实际上都不是有效的awk脚本。您也不应该使用旧的和过时的back tics,而是使用如下括号:
var=$(echo“02.Port”| grep-o“[1-9]”谢谢你的评论!。我将开始使用$()而不是背面的ticsthank作为回复。我要做的是执行这个命令。echo“2-4”| tee/sys/bus/usb/drivers/usb/unbind(然后再次绑定)。我需要编写一个脚本来查找总线和端口号,以便执行该命令。我在想另一种方法,比如ls/sys/bus/usb/drivers/usb | grep“-”,这将返回我需要的东西。但是我想学习,如果你知道用lsusb命令实现这一点的另一种方法,那就太好了!我从来没有听说过lsusb命令,所以我也不知道你说的“然后再绑定”是什么意思。我不知道你在哪个领域工作。我所知道的是如何使用shell命令,使用awk和/或其他UNIX工具将文本从一种格式转换为另一种格式,因此,如果您需要这方面的帮助,请更新您的问题,以显示所需的示例输入和预期输出。如果您只是想
执行此命令。echo“2-4”| tee/sys/bus/usb/drivers/usb/unbind
然后继续执行该命令,但这似乎与您发布的输入完全无关。我已经用您请求的信息更新了问题。谢谢你的帮助!好的,我已经更新了我的答案以匹配,并展示了如何在没有单独的回声、球座和管道的情况下完成我认为您最终想要的。是的,非常感谢您的帮助。不确定为什么bind和unbind命令不起作用。但这可能是另一个问题,我将继续了解这一点。再次感谢!我认为他的脚本中的
$3
应该是每行输入的第三个字段,而不是传递给shell脚本的第三个参数。正确的是,如果您已经在使用awk,就不会使用grep。
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
        }
    }
}