파일을 패턴 목록으로 사용하여 awk 필터링 라이브 캡처

파일을 패턴 목록으로 사용하여 awk 필터링 라이브 캡처

내가 하려는 일은 아주 간단하다. 출력을 생성하고 파이프를 사용하여 tshark리디렉션하고 있습니다 . 라이브 데이터를 가져 오므로 모든 출력에서 ​​파일의 첫 번째 열("target.txt")에 있는 패턴(이미 가지고 있는 일부 MAC 주소)을 검색하고 일치하는 경우 첫 번째 및 이 파일의 두 번째 열입니다.awk|tsharkawkawk

다음의 예 target.txt:

ab:cd:ef:gh:ij:kl,Me
12:34:56:78:90:10,You
1b:2d:3f:4h:5j:6l,someone

모든 것을 더 쉽게 만들기 위해 tshark출력에는 열이 2개만 있고 MAC 주소 열은 두 번째 열입니다.

한 줄의 tshark출력은 다음과 같습니다.

Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 
           ^^^^- date and MAC are separated by tab!

따라서 tshark만 발견 12:34:56:78:90:10하면 awk출력됩니다.

12:34:56:78:90:10 -> You

또는 더 나은:

Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You

편집 #1

글쎄요, 몇 가지 테스트를 해보니 tsharks 출력이 \t로 구분되어 있다는 것을 알았습니다 tab. 큰 문제는 아니지만 이미 작은 개선이 이루어졌습니다. 문제는 출력에서 ​​샘플을 얻었고 파이프 이전 명령을 tshark통해 Gnoucs 답변으로 테스트했다는 것입니다 . 효과가 있었습니다. 그런 다음 for 를 변경했고 모든 것이 작동을 멈췄습니다 =).echo|echotshark

라이브 데이터에 문제가 있는 걸까요? 지금까지 내 코드는 다음과 같습니다.

$ tshark -I -i wlan0 -T fields -e radiotap.dbm_antsignal -e wlan.sa | awk -F'[ ,\t]' '
     FNR == NR { a[$1] = $2 }
     ($NF in a) { print $0" -> "a[$NF] }
 ' alvos.txt -

글쎄, 방금 성공했어! 아마도 오타였을 겁니다. 모든 답변에 감사드립니다!

답변1

이 시도:

$ awk -F'[ ,\t]' '
    FNR == NR { a[$1] = $2 }
    ($NF in a) { print $0" -> "a[$NF] }
' target.txt -

예:

$ awk -F'[ ,\t]' '
    FNR == NR { a[$1] = $2 }
    ($NF in a) { print $0" -> "a[$NF] }
' target.txt -
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 # Ctrl + D here
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You

설명

  • -F[ ,\t]: 필드 구분 기호로 쉼표, 공백 또는 탭을 사용합니다.
  • FNR == NR { a[$1] = $2 }: FNR == NR첫 번째 파일을 처리할 때만 true입니다. 따라서 의 각 줄에서 target.txt두 번째 필드를 연관 배열에 저장하고 첫 번째 필드(MAC 주소)는 인덱스입니다.
  • ($NF in a): 입력을 읽을 때( 입력에서 읽은 -후 ) 마지막 필드가 연관 배열이면 원하는 결과를 인쇄합니다.target.txtawka

답변2

내가 올바르게 이해했다면 다음 중 하나가 최소한 원하는 결과를 생성할 것입니다.

${TSHARK} |
sed -n "$(IFS=',
';  printf '/%s/s//& -> %s/p\n' \
        $(cat target.txt)
)"


${TSHARK} | 
sed -n "$(
   sed 's/,/|s||\& -> /
        s/.*/\\|&|p/
   ' <target.txt
)"

나는 이것을 다음과 같은 방법으로 테스트했습니다.

printf 'ab:cd:ef:gh:ij:kl,Me
12:34:56:78:90:10,You
1b:2d:3f:4h:5j:6l,someone' >./target.txt

printf 'Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10' |
sed ...

그리고 이것이 내 결과였습니다.

Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You

답변3

#!/usr/bin/env awk
# filename ~/mac-lookup.awk

function load_mac_list (filename, array) {
    while ((getline line < filename) > 0) {
        split(line, fields, ",");
        array[fields[1]] = fields[2];
    }
    close(filename)
}

BEGIN {
    load_mac_list("target.txt", mac_list);
}

($5 in mac_list) {
    print $0 " -> " mac_list[$5];
    next;
}

{
    print;   # remove this line to avoid printing unmatched lines
}

무차별 대입 접근 방식은 다음과 같습니다. 대상 파일을 로드한 다음 mac 주소가 목록에 있는 경우에만 mac 별칭을 인쇄합니다.

이 경우 "target.txt"는 awk 스크립트에 하드코딩되어 있습니다. Gnouc의 답변에서 원하는 대로 대상 목록 파일 이름을 스크립팅할 수 있습니다.

용법

$ ${TSHARK} | awk -f ~/mac-lookup.awk
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
Jun 16, 2014 02:55:51.300286010 zy:xw:vu:ts:rq:po
Jun 16, 2014 02:55:51.300286020 ab:cd:ef:gh:ij:kl -> Me

관련 정보