Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用一个awk命令在匹配字符串中搜索字符串_Awk - Fatal编程技术网

使用一个awk命令在匹配字符串中搜索字符串

使用一个awk命令在匹配字符串中搜索字符串,awk,Awk,我想使用awk搜索匹配字符串中的字符串。但是awk和我发现只有一个匹配项,或者有答案,所以我不能轻易地从他们那里得出一般原则来解决我的问题 例如,我想从带有如下文本的cat/proc/bus/input/devices命令中获取“Thinkpad额外按钮”设备的事件处理程序编号: I: Bus=0011 Vendor=0001 Product=0001 Version=ab54 N: Name="AT Translated Set 2 keyboard" H: Handlers=sysrq kb

我想使用awk搜索匹配字符串中的字符串。但是awk和我发现只有一个匹配项,或者有答案,所以我不能轻易地从他们那里得出一般原则来解决我的问题

例如,我想从带有如下文本的
cat/proc/bus/input/devices
命令中获取“Thinkpad额外按钮”设备的事件处理程序编号:

I: Bus=0011 Vendor=0001 Product=0001 Version=ab54
N: Name="AT Translated Set 2 keyboard"
H: Handlers=sysrq kbd event3 
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe

I: Bus=0019 Vendor=17aa Product=5054 Version=4101
N: Name="ThinkPad Extra Buttons"
P: Phys=thinkpad_acpi/input0
H: Handlers=rfkill kbd event7 
B: KEY=18040000 0 10000000000000 0 101501b00102004 8000000001104000 e000000000000 0

I: Bus=0003 Vendor=04f2 Product=b2ea Version=0518
N: Name="Integrated Camera"
P: Phys=usb-0000:00:1a.0-1.6/button
cat /proc/bus/input/devices | awk '/Think/,/event/ {print}; /event/ {print $2} 
产生类似于

H: Handlers=rfkill kbd event7
使用我可以抓取“Thinkpad额外按钮”块,然后尝试添加另一种搜索模式,如下所示:

I: Bus=0011 Vendor=0001 Product=0001 Version=ab54
N: Name="AT Translated Set 2 keyboard"
H: Handlers=sysrq kbd event3 
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe

I: Bus=0019 Vendor=17aa Product=5054 Version=4101
N: Name="ThinkPad Extra Buttons"
P: Phys=thinkpad_acpi/input0
H: Handlers=rfkill kbd event7 
B: KEY=18040000 0 10000000000000 0 101501b00102004 8000000001104000 e000000000000 0

I: Bus=0003 Vendor=04f2 Product=b2ea Version=0518
N: Name="Integrated Camera"
P: Phys=usb-0000:00:1a.0-1.6/button
cat /proc/bus/input/devices | awk '/Think/,/event/ {print}; /event/ {print $2} 
我得到了所有不相关的处理程序行,而不仅仅是“Thinkpad额外按钮”行


我意识到我可以将该范围模式的结果通过管道传输到单独的awk命令中,并在H:Handlers行上进行搜索。然而,当我想找到多个Thinkpad命名设备时,这不起作用,但实际上似乎awk应该能够做这类事情,我还没有弄明白,这让我很恼火。

这里有一个可能对你有用的快速解决方案:

awk '
/^N: Name="ThinkPad Extra Buttons"$/ { found = 1; }
/^H: Handlers=/ { handlers = $0; }
$0 == "" { endRecord(); }
END { endRecord(); }
function endRecord() {
    if (found) {
        print handlers;
        found = 0;
    }
}
' file.txt
这样做的目的是:

  • 准确地查找“ThinkPad”行,使用它来标记您正在查看您关心的记录

  • 注意所有“H”处理程序行的内容

  • 在每个“记录”的末尾打印处理程序行,其中每个“记录”由一个空行分隔。(注意:这不是Awk记录;就Awk而言,每一行都是一条记录。)


这种问题很适合段落处理,而不是行处理。 使用GNU awk:

gawk -v RS='' '
    /N:.*ThinkPad Extra Buttons/ {
        match($0, /(H:.*event[0-9]+)/, a)
        print a[0]
        exit
    }
' /proc/bus/input/devices
如果您愿意超越awk:

perl -00 -lne 'if (/^N: Name=.ThinkPad Extra Buttons/m) {print /^(H:.*)$/m; exit}' /proc/bus/input/devices

以上两个答案都有效,但它一直困扰着我,认为应该有一个超短的方法来做到这一点

这就是我想到的:

awk '/Think/,/event/ {if(/event/) {print $4}}' /proc/bus/input/devices

这背后的原理是,它在一个范围内匹配,然后在第一组花括号内,我可以对捕获的行进行逐行处理。

这可以实现如下。。。。 1) 让我们假设我有下面的排序输出,从我需要它被awk处理的地方

$ grep mouse /proc/bus/input/devices
N: Name="Macintosh mouse button emulation"
H: Handlers=mouse0 event1
H: Handlers=mouse1 event3




   $ awk '/Macintosh /,/event/ {if(/event/) {print $2,$3}}' /proc/bus/input/devices
    Handlers=mouse0 event1
下面对我不适用

$ awk '/Macintosh /,/event/ {if(/event/) {print $4}}' /proc/bus/input/devices

永远不要使用“记录范围模式”。它们使解决琐碎的问题变得稍微简单,但即使是像你这样的琐碎问题也不能建立在它们之上。谢谢你对你在那里所做的事情的良好解释。我会把这个技巧放在我的awk技巧包里谢谢你的回答。-vrs部分背后的想法是什么?awk变量RS是记录分隔符。默认情况下,它是
\n
,因此每一行都是一条记录。将其设置为空字符串允许您将空行分隔段落作为记录。请参阅GNU awk手册,这是有道理的——在上面的Thinkpad示例文本中,有四个实体,在您使用的mac示例中,只有三个实体。此外,由于您是新来的,我建议您阅读关于将评论发布为答案的社区指南