xev | awk -F'[ )]+' '/^KeyPress/ { a[NR+2] } NR in a { printf "%-3s %s\n", %5, %8}
xevを使用する場合は、特定の情報のみが必要です。キーコード情報を取得するためにxevを使用する場合の自然な反応は次のとおりです。
KeyPress event, serial 48, synthetic NO, window 0x1600001,
root 0xf6, subw 0x0, time 754405, (348,566), root:(349,620),
state 0x0, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XmbLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
KeyRelease event, serial 48, synthetic NO, window 0x1600001,
root 0xf6, subw 0x0, time 754488, (348,566), root:(349,620),
state 0x0, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
AWKスクリプトの結果は次のように返されます。
40 d
AWKを学びたいのですが:)
それで、NRを学び、いくつかのチュートリアルを行った後、この問題を解決しようとしています。まず -F は '[ ]]+' フィールドを分割します。この場合には、1 つ以上の空白や閉じ括弧に対する正規表現と考えられます。私は理解できません。前置詞の前に空白が見えません。また、私は\ sのようなスペースツールについてのみ学んだので、ここで正規表現ボックスのスペースが何をしているのかわかりません。したがって、どのフィールドに$ 5と%8が表示されているかを確認したいと思います。分析結果が正しくないので混乱しているからです。
echo "state 0x0, keycode 12 (keysym 0x33, 3), same_screen YES," | awk '{print $8}'
same_screen
echo "state 0x0, keycode 12 (keysym 0x33, 3), same_screen YES," | awk '{print $5}'
(keysym
編集:だからこれは何ですか printf "%-3s %s\n", $5, $8}
?出力が上記のエコー例となぜそんなに違うのですか?
明らかにこれは魔法に由来するものです{a[NR+2] NR in a}
。一種の配列とforループ。
NR+2を見て考えるようになりました。 AWKが起動すると、NRは1から始まるので、2を追加すると3行目になります。私が望むすべての情報が3行目にあるので、これは正しいようです。
[NR+2]で何が起こっていますか? printfのNRのために…?私はprintfを理解し、forループを理解します。ここでNRの使用方法は私を混乱させます。
本当の質問は「a」に何が起こったのかと思います。これは私が知らない事前定義されたものですか?
答え1
あなたは何かを正しく{a[NR+2]} NR in a { ... }}
推測したようです。
/^KeyPress/ {a[NR+2]}
行の先頭が文字列と一致する場合は、a
インデックス付きの配列に(null)要素を作成します。NR+2
NR
KeyPress
NR in a
/^KeyPress/
したがって、次の2行が一致するのは正しいです。
この点で、おそらく次のようにより透明に書くことができます。
awk -F'[ )]+' '/^KeyPress/ {n=NR+2} NR==n { printf "%-3s %s\n", $5, $8}'
おそらくもっと難しい質問は、印刷されるフィールドがandの代わりにandで$5
ある$8
理由$4
です$7
。これは、デフォルト以外のフィールド区切り文字を使用すると、初期スペースが異なるように処理されるためです。基本フィールド分割GNUawk
マニュアルセクション:
フィールドは通常、単一のスペースではなく、一連のスペース(スペース、タブ、および改行)で区切られます。 1行の2つのスペースは空のフィールドを区別しません。フィールド区切り文字FSのデフォルト値は、単一のスペース""を含む文字列です。 awkが通常の方法で値を解釈する場合、各スペース文字はフィールドを区切るため、1行の2つのスペースはフィールド間に空のフィールドを形成します。これが発生しない理由は、FS値で単一のスペースが特殊な場合であるためです。これは、フィールドを区別する基本的な方法を指定するために使用されます。
FSが「、」などの他の単一文字の場合、その文字が表示されるたびに2つのフィールドが区別されます。 2回連続して発生すると、空のフィールドが定義されます。この文字が行の先頭または末尾に表示されると、空のフィールドも区別されます。空白文字は、これらの規則に従わない唯一の単一文字です。
答え2
%-3s
文字列が、左側ではなく右側にスペースが埋め込まれた3文字の幅フィールドに印刷されることを示します。だから印刷されます
40 d
代わりに
40 d
答え3
私は助けることができますが、ここで誰かがもっと深い答えを提供することができます。しかし、それを分解してみましょう。
まず|を使用してxevの出力をawkにパイプします。
あなたは正しいです。 -FはAwkの列区切り文字を定義し、その文字と一致する正規表現は[)] +
提供された出力例では一度だけ一致します。それ以降のすべてはawkスクリプトです。
/^KeyPress/ は、「KeyPress」で始まる改行文字を探す別の正規表現です...重複しているようです。
printf の引数はコンマで区切られ、最初の引数は型なので、 "%-3s %s\n" は型です。参照とここ
{printf "%-3s %s\n", %5, %8} は { printf "%-3s %s\n", $5, $8} にできますか?
私はこれをよく理解していません。他人が解読できることを願っています!ところで - あなたは使用することができますこれ正規表現テストを手伝ってください。