이 AWK 스크립트를 해독하세요.

이 AWK 스크립트를 해독하세요.
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를 추가하면 세 번째 행이 됩니다. 내가 원하는 모든 정보가 세 번째 행에 있으므로 이는 올바른 것 같습니다.

[NR+2]에 무슨 일이 일어나고 있나요? printf의 NR을 위해...? 나는 printf를 이해하고 for 루프를 이해합니다. 여기서 NR이 사용되는 방식은 나를 혼란스럽게 합니다.

진짜 질문은 "a"에게 무슨 일이 일어났는가 하는 것 같아요. 이것은 내가 모르는 사전 정의된 것입니까?

답변1

당신은 뭔가를 올바르게 {a[NR+2]} NR in a { ... }}추론한 것 같습니다.

  • /^KeyPress/ {a[NR+2]}줄의 시작이 문자열과 일치하는 경우 a인덱스가 있는 배열에 (null) 요소를 만듭니다.NR+2NRKeyPress
  • NR in a/^KeyPress/따라서 다음 두 줄이 일치하는 것이 맞습니다.

이런 점에서 아마도 다음과 같이 더 투명하게 작성될 수 있을 것입니다.

awk -F'[ )]+' '/^KeyPress/ {n=NR+2} NR==n { printf "%-3s %s\n", $5, $8}'

아마도 더 까다로운 질문은 인쇄되는 필드가 $5and $8대신 $4and 인 이유입니다 $7. 이는 기본이 아닌 필드 구분 기호를 사용할 때 초기 공백이 다르게 처리되기 때문입니다.기본 필드 분할GNU awk매뉴얼 섹션:

필드는 일반적으로 단일 공백이 아닌 일련의 공백(공백, 탭 및 줄 바꿈)으로 구분됩니다. 한 줄에 있는 두 개의 공백은 빈 필드를 구분하지 않습니다. 필드 구분자 FS의 기본값은 단일 공백 ​​""을 포함하는 문자열입니다. awk가 일반적인 방식으로 값을 해석하는 경우 각 공백 문자는 필드를 구분하므로 한 줄에 있는 두 공백은 필드 사이에 빈 필드를 형성합니다. 이것이 발생하지 않는 이유는 FS 값으로 단일 공백이 특수한 경우이기 때문입니다. 이는 필드를 구분하는 기본 방법을 지정하는 데 사용됩니다.

FS가 ","와 같은 다른 단일 문자인 경우 해당 문자가 나타날 때마다 두 필드가 구분됩니다. 두 번 연속 발생하면 빈 필드가 정의됩니다. 이 문자가 줄의 시작이나 끝 부분에 나타나면 빈 필드도 구분됩니다. 공백 문자는 이러한 규칙을 따르지 않는 유일한 단일 문자입니다.

답변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} 일 수 있습니까?

나는 이것을 잘 이해하지 못한다. 다른 사람이 해독할 수 있기를 바랍니다! 그런데 - 당신은 사용할 수 있습니다이것정규식 테스트를 도와주세요.

관련 정보