3

awkを使用して、一致する文字列内の文字列を検索したいと思います。しかし、私が見つけたawkガイド例は1つの一致しか採用していないか、有望なSOの質問には非常に具体的な回答があるため、問題を解決するためにそれらから一般的なプリンシパルを簡単に引き出すことはできません。

cat /proc/bus/input/devicesたとえば、次のようなテキストを含むコマンドから「ThinkpadExtraButtons」デバイスのイベントハンドラー番号を取得したいとします。

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

次のような出力を生成するには

H: Handlers=rfkill kbd event7

レコード範囲パターンを使用すると、「Thinkpad Extra Buttons」ブロックだけを取得できますが、次のような別の検索パターンを追加しようとしています。

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

「ThinkpadExtraButtons」の行だけでなく、関連のないすべてのHandlers行を取得します

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

その範囲パターンの結果を別のawkコマンドにパイプして、H:Handlers行で検索できることに気付きました。ただし、Thinkpadという名前のデバイスを複数見つけたい場合は機能しませんが、実際にはawkがこの種のことを実行できるはずであり、まだ理解していないので困っています。

4

4 に答える 4

6

この種の問題は、行単位ではなく、段落単位の処理に適しています。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
于 2013-03-19T20:57:13.057 に答える
3

これがあなたのために働くかもしれない簡単な解決策です:

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に関する限り、各行はレコードです。)

于 2013-03-19T18:41:47.660 に答える
1

上記の答えは両方とも機能しますが、これを行うには非常に短い方法があるはずだと私は悩み続けました。

これは私が思いついたものです:

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

この背後にある主な点は、範囲内で一致することです。次に、中括弧の最初のセット内で、キャプチャされた行に対して行ごとの処理を実行できます。

于 2013-03-21T17:09:57.387 に答える
0

これは以下のように達成できます....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
于 2016-04-20T08:54:10.347 に答える