繁体   English   中英

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

[英]AWK error - syntax error at or near grep

我需要创建一个脚本来将一台Linux计算机上的所有USB解除绑定/绑定。

为此,我需要运行:

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;

我尝试了所有可能的组合以设置var。 我总是会出错。

awk: line 8: syntax error at or near grep

谁能提出解决方案或其他方法?

谢谢阅读。

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

感谢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

我想解析此信息以获得总线号和端口号。 因此输出应为:

2-1
2-4
2-6
2-6
1-1

但是,我只需要“子”端口,因此需要以下输出:

2-4
2-6
2-6

再次感谢!

shell是一种从中调用UNIX工具的环境,该语言具有对这些调用进行排序的语言。

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

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

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

您将从外壳调用grep来找到一个正则表达式并打印匹配的行。

您可能会从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

请注意,如果您希望将其移至几个文件以及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
    }
}

并且由于对已经处理的总线+端口组合重复操作似乎毫无意义(例如第二个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
        }
    }
}

您不能在awk定义变量

var= $(echo $3 | grep -o "[1-9]"

做这样的事情:

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

PS我不明白为什么你需要同时使用awkgrep

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM