Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use one awk command to search for a string within a matching string

Tags:

awk

I want to use awk to search for a string within a matching string. But the awk guides and examples I've found only employ one match, or promising sounding SO questions have answers so specific that I can't easily draw general principals from them to solve my issue.

For example, I want to get the event handler number for the "Thinkpad Extra Buttons" device from a cat /proc/bus/input/devices command with text like this:

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

To produce output that looks something like

H: Handlers=rfkill kbd event7

Using record range patterns I can grab out just the "Thinkpad Extra Buttons" block, but then trying to add another search pattern like this:

cat /proc/bus/input/devices | awk '/Think/,/event/ {print}; /event/ {print $2} 

I get all the unrelated Handlers lines, not just the one for "Thinkpad Extra Buttons"

Handlers=event0
Handlers=kbd
Handlers=kbd
Handlers=sysrq
N: Name="ThinkPad Extra Buttons"
P: Phys=thinkpad_acpi/input0
S: Sysfs=/devices/platform/thinkpad_acpi/input/input7
U: Uniq=
H: Handlers=rfkill kbd event7 
Handlers=rfkill
Handlers=kbd
Handlers=event9
Handlers=event10

I realize I could pipe the results of that range pattern into a separate awk command and search on the H: Handlers line. However that doesn't work when I want to find multiple Thinkpad named devices, but really it seems like awk should be able to do this kind of thing and it bugs me that I haven't figured it out yet.

like image 670
Rian Sanderson Avatar asked Mar 17 '26 17:03

Rian Sanderson


1 Answers

This kind of problem lends itself well to paragraph-wise processing, rather then line-wise. With GNU awk:

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

If you're willing to stretch beyond awk:

perl -00 -lne 'if (/^N: Name=.ThinkPad Extra Buttons/m) {print /^(H:.*)$/m; exit}' /proc/bus/input/devices
like image 140
glenn jackman Avatar answered Mar 19 '26 05:03

glenn jackman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!