จับคู่สตริงใน awk


1

ฉันจะค้นหาไฟล์เพื่อค้นหาบรรทัดที่มี SRC = ได้จากที่นี่ได้อย่างไร ฉันหมายถึงฉันจะหาที่อยู่ IP ต้นทางในไฟล์นี้โดยใช้ awk ได้อย่างไร

Mar 10 03:17:12 ubuntu kernel: [11045.721649] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.28 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=47 ID=6603 PROTO=TCP SPT=47301 DPT=53 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:12 ubuntu kernel: [11045.721702] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.30 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=42 ID=6802 PROTO=TCP SPT=47301 DPT=5900 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:32 ubuntu kernel: [11065.703937] Type=ScanACKIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.31 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=40 ID=62992 PROTO=TCP SPT=47301 DPT=1521 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:32 ubuntu kernel: [11065.706729] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.32 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=47 ID=15170 PROTO=TCP SPT=47301 DPT=14442 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0

แล้วฉันต้องการได้รับผลลัพธ์นี้:

192.168.1.28
192.168.1.30
192.168.1.31
192.168.1.32

มีหลายบรรทัด (100,000) และฉันต้องการค้นหา SRC = แล้วเมื่อฉันค้นหาการครอบตัดบรรทัด SRC = และเพียงแค่หาที่อยู่ IP

ใช้ AWK

ขอบคุณทุกคน! :)


เดมันจำเป็นต้องมีawkหรือจะgawkโอเค?
terdon

awk เป็นที่ต้องการ แต่ไม่ไร้อำนาจเลย
Arash

awk '(/SRC=192.168.1.28/) {พิมพ์ $ 11}' แต่ฉันต้องการแค่ที่อยู่ IP
Arash

match()เพียงแค่ขอให้เพราะคุณสามารถจับภาพการแข่งขันในการเพ่งพิศกับ
terdon

คำตอบ:


5

น่าเสียดายที่ awk ไม่ได้จับภาพกลุ่มของมัน คุณอาจต้องการมองหาเครื่องมือที่ทันสมัยกว่าที่จะเขียนหนึ่ง liners เช่น Perl

วิธีที่เร็วที่สุดในกรณีของคุณขึ้นอยู่กับว่า SRC = จะอยู่ในที่เดียวกันเสมอในบันทึกหรือไม่

หากมันอยู่ในสถานที่เดียวกันเสมอและข้อโต้แย้งนั้นมีเครื่องหมายเท่ากับจำนวนเท่ากันคุณสามารถแบ่งบรรทัดของคุณออกเป็นสองส่วนเท่ากันและเว้นวรรคแล้วนำเขตข้อมูลที่ 15:

awk -F'[= ]' '{print $15}'

มิฉะนั้นสำหรับแนวทางที่มีประสิทธิภาพมากขึ้นคุณสามารถแทนที่ส่วนที่นำไปสู่ ​​SRC = และส่วนที่ตามมา:

awk '{sub(/.* SRC=/, ""); sub(/ .*/, ""); print;}'

หากคุณต้องการนับเหตุการณ์ที่เกิดขึ้นคุณสามารถเพิ่มสำนวน| sort | uniq -c | sort -rnให้กับไปป์ไลน์ แต่มันไม่มีประสิทธิภาพกับ 100,000 บรรทัด คุณควรใช้ประเภทพจนานุกรมในตัวของ awk ในสองขั้นตอนแรก:

awk '{sub(/.* SRC=/, ""); sub(/ .*/, ""); ips[$0]++;}
     END {for (ip in ips) printf("%8d  %s\n", ips[ip], ip);}' | sort -nr

ผลลัพธ์ของทั้งสองควรมีลักษณะเช่นนี้:

7513  192.168.1.28
 330  192.168.1.30
 103  192.168.1.31
  19  192.168.1.32

มันใช้งานได้ดีขอบคุณ: *: D แต่ 1 คำถามว่าฉันจะทรายได้อย่างไรถ้า 1 ip ปรากฏขึ้น 3 ครั้ง echo ในไฟล์ในบรรทัดใหม่
Arash

ฉันไม่เข้าใจคำถามสุดท้ายนี้
Tobia

4

แม้ว่านี่จะเป็นไปได้ด้วย awk แต่มันก็ตรงไปตรงมามากกับ grep:

grep -Po "(?<=SRC=)[\d.]+"

มันทำงานอย่างไร:

  • -Pช่วยให้นิพจน์ปกติ Perl เข้ากันได้

  • -o แสดงเฉพาะส่วนที่ตรงกันของบรรทัด

  • (?<=SRC=)เป็นลักษณะที่อยู่เบื้องหลังบวกยืนยันคือการแข่งขันต้องนำหน้าด้วยsrc =

  • [\d.]+ คือจำนวนหลักและจุดใด ๆ


2

โซลูชัน sed (sed เป็นมาตรฐานเท่ากับ awk ในระบบ UNIX):

sed -n -e 's/.*SRC=\([^ ]*\).*/\1/p' -e 's/.*SRC=\([^ ]*\)$/\1/p' file

สิ่งที่พยายามลบทุกอย่างก่อนSRC=และหลังช่องว่างถัดไป เมื่อการทดแทนเสร็จสิ้นให้พิมพ์บรรทัดผลลัพธ์ การทดแทนที่สองเป็นสิ่งจำเป็นหากที่อยู่ IP เป็นเขตข้อมูลสุดท้ายของบรรทัด



2

บริสุทธิ์นี้ใช้awkงานได้แม้ว่าจำนวนฟิลด์จะเปลี่ยนแปลงตราบใดที่ IP ที่ต้องการนำหน้าSRC=และตามด้วยช่องว่าง:

awk -F'SRC=' '{print $2}' a | awk '{print $1}'

นี่อาจจะตรงไปตรงมามากกว่าgawkซึ่งมีmatch()ฟังก์ชั่นที่ให้คุณจับภาพได้:

gawk 'match($0,/SRC=([0-9.]+)/,k){print k[1]}' a

1

อีกวิธีหนึ่งawkในการลองยกเลิกเส้นที่ไม่มีSRC=:

awk -F'.*SRC=| ' '/SRC=/{print $2}' file

หรือลองอีกครั้งsed:

sed -n '/.*SRC=/{s///; s/ .*//p;}' file
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.