ฉันสามารถใช้นิพจน์ทั่วไปเพื่อจับคู่ที่อยู่ IP ได้อย่างไร


35

ด้วยgrepไวยากรณ์ต่อไปนี้ฉันต้องการจับคู่ที่อยู่ IP ทั้งหมดในไฟล์ (จากkshสคริปต์)

  grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' file

ปัญหา: มันตรงกับคำ (IP) ที่มีมากกว่า 4 octets:

1.1.1.1.1 

หรือ

192.1.1.1.160

ฉันจะจับคู่IP ที่ถูกต้องและที่อยู่ IP กับ 4 octets ได้อย่างไร ฉันยังสามารถใช้ Perl - โซลูชันไวยากรณ์หนึ่งบรรทัดถ้าgrepไม่ทำงาน


4
มันจะจับคู่999.999.999.999กัน
cYrus

4
ดังนั้นคุณต้องการ grep ที่อยู่ IPv4 ใช่ไหม
Arjan

5
ในทางเทคนิคที่อยู่ IP เช่น192.1.4097ถูกต้องและยอมรับโดย Linux glibc และ Windows
grawity

1
อ่าฉันไม่เคยรู้เลย! ping 2130706433บน OS PING 2130706433 (127.0.0.1): 56 data bytesX:
Arjan

1
@Arjan: 0x7f.1และ0177.1
grawity

คำตอบ:


56

ลองนี้:

grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hosts

ซึ่งจับคู่นิพจน์ทั้งหมดตั้งแต่0.0.0.0ถึง999.999.999.999

กับ

grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hosts

คุณจะได้รับที่อยู่ IP เท่านั้น

หมายเหตุ:
บนโซลาริสอาจegrepจะทำงาน


ฉันลอง grep '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / hosts แต่ฉัน ไม่ได้รับอะไรเลย: :(
jennifer

1
@ เจนนิเฟอร์คุณจะต้องเปิดใช้งานนิพจน์ทั่วไปเพิ่มเติม: grep -E <pattern> <file>(หรือเพื่อพิมพ์การแข่งขัน:grep -Eo <pattern> <file>
Arjan

อย่างนี้ ? grep -E '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / ไพร่พล
เจนนิเฟอร์

3
@udo: การแข่งขันนี้ดี1.1.1.1.1แต่มันซ่อนสุดท้าย.1จากผลลัพธ์ฉันไม่เห็นว่ามันจะช่วยได้อย่างไร
cYrus

1
regexp ของคุณไม่ตรงกับ 10.0.0.1
Stefan Seidel

10

เป็นอย่างไรบ้าง:

perl -MRegexp::Common=net -ne '/($RE{net}{IPv4})/ and print "$1\n"' /etc/hosts

ดี! (นี่ยังส่งกลับ192.1.1.1.160เป็น192.1.1.1ซึ่งผมคิดว่าเป็นสิ่งที่ดีสำหรับการถามคำถาม.)
Arjan

2
หากต้องการที่อยู่ IP ที่สอดคล้องกันจริง ๆ นี่เป็นโซลูชันชนิดเดียวที่มีโอกาสใกล้ที่จะเสร็จสมบูรณ์ เมื่อฉันเห็นคำถามฉันแค่คิดว่า "ฉันจะไม่แตะต้องด้วยเสา regexp มาตรฐานสิบฟุต" Caveats, caveats ได้ทุกที่ :-)
Daniel Andersson

5

-w / --word-regexp 

ตั้งค่าสถานะเพื่อให้grepตรงกับขอบเขตของคำเท่านั้นหมายความว่าการจับคู่ของคุณต้องล้อมรอบด้วยช่องว่างหรือเริ่มต้น / สิ้นสุดที่จุดเริ่มต้น / สิ้นสุดของบรรทัด!


5

หากต้องการค้นหาการแข่งขันที่มี 4 อ็อกเท็ตอย่างแน่นอน (ยกเว้นสิ่งต่าง ๆ เช่น 1.1.1.1.1) ให้ใช้สิ่งนี้:

grep -P '(?<=[^0-9.]|^)[1-9][0-9]{0,2}(\.([0-9]{0,3})){3}(?=[^0-9.]|$)'

มันไม่ควรตรวจจับที่ไม่ใช่ที่อยู่ IP นิพจน์อาจมีความซับซ้อนมากขึ้นในการตรวจสอบสิ่งต่าง ๆ เพิ่มเติม แต่สิ่งนี้ควรใช้ในกรณีส่วนใหญ่ มันจะไม่ตรงกับ 0 ก่อนหน้านี้เนื่องจาก 010.1.12.1 ไม่ใช่วิธีทั่วไปในการเขียนที่อยู่ IP


5
if [ ` echo $ip | '^((25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'  | grep -o "\." | wc -l` -eq 1 ];
then ipv4=true;
else 
ipv4=false;

3

ยุ่งยากเล็กน้อย แต่ควรใช้งานได้:

( X='\([0-9]\{1,2\}\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)' ; grep "\([^\.]\|^\)$X\.$X\.$X\.$X\([^\.]\|$\)" file )

สิ่งที่เกี่ยวกับ127.000.000.001แล้ว? ;-)
Arjan October

เท่าที่ฉันรู้ว่า IP ไม่มีช่องว่างภายใน
cYrus

1
อืมใช้ping 127.000.000.001งานได้กับ Mac ของฉันอย่างแน่นอน แต่แล้ว: ฉันเพิ่งเรียนรู้ว่าแม้จะping 2130706433ให้ผลลัพธ์ที่เหมือนกันมาก :-) อ๊ะแปลว่าping 00127.00000.00000.00001 87.0.0.1คี่ ... หรือเลขฐานแปดอาจจะ? ใช่เลขฐานแปดแน่นอนดังนั้นคุณถูกต้องเกี่ยวกับศูนย์นำฉันเดา
Arjan

ใช่ 00127 (ฐานแปด) = 87 (ฐานสิบ) แน่นอนว่าพวกเขาเป็น IP ที่ถูกต้องทั้งหมด แต่ฉันคิดว่านั่นไม่ใช่วิธีมาตรฐานในการเป็นตัวแทนพวกเขา อย่างไรก็ตามผู้ถามไม่ได้ร้องขอ
cYrus

0

grep -E '^ ((25 [0-5] | 2 [0-4] [0-9] | [1]? [1-9] [0-9]?).) {3} (25 [ 0-5] | 2 [0-4] [0-9] |? [1] [1-9] [0-9]) $'

แก้ไขคำตอบของ Arnaud B. แล้ว

นิพจน์นี้จะไม่ตรงกับที่อยู่ IP กับเลข 0 นำหน้า เช่นมันจะไม่ตรงกับ 192.168.1.01 นิพจน์นี้จะไม่ตรงกับที่อยู่ IP ที่มีมากกว่า 4 octets เช่นมันจะไม่ตรงกับ 192.168.1.2.3


สิ่งนี้จะไม่ตรงกับ 127.0.0.1 เช่นกัน
Chris Charabaruk

0

ฉันใช้egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts เพื่อจับคู่ที่อยู่ IP ที่จุดเริ่มต้นของบรรทัด นอกจากนี้ยังสามารถใช้งานได้โดยไม่ต้องมี^ช่องว่างสีขาวหรือตัวอักษรอื่น ๆ ก่อนที่จะอยู่ IP

[0-9]{1,3} --> this matches a number between 1 and 999.
\. --> this is to add the dot.
([0-9]{1,3}\.){3} --> get a number with a dot 3 times.
[0-9]{1,3} --> finally add the fourth number.

0

regex รุ่นที่สั้นกว่า:

egrep '([1-2]?[0-9]{0,2}\.){3,3}[1-2]?[0-9]{0,2}' 

กรุณาใช้ grep -E หรือ egrep ตามความเหมาะสมกับเวอร์ชั่นระบบปฏิบัติการของคุณ


2
ยินดีต้อนรับที่ superuser คำถามนี้มีคำตอบที่ดีอยู่แล้วหลายข้อ เพื่อช่วยให้ผู้คนเข้าใจความแตกต่างระหว่างพวกเขาโปรดแก้ไขคำตอบของคุณและอธิบายสิ่งที่ทำให้ดีขึ้น / แตกต่างจากคนอื่น
MátéJuhász

การแสดงออกนี้ไม่ได้คำนึงถึง ips ตามกฎหมายเช่น 8.8.8.8 echo "8.8.8.8" | grep -Eo '([1-2][0-9]{0,2}\.){3,3}[1-2][0-9]{0,2}'=> ไม่มีผลลัพธ์
anneb


0

นิพจน์ปกติสำหรับจับคู่ที่อยู่ IP ใน TCL

ตั้งค่า "192.168.10.25"

if {[regexp
{^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$} $a]} 
{
    puts "yes"
}

-1

นี่คือสิ่งที่ทำงานสำหรับฉันสำหรับ ksh และ ksh93 ใน AIX:

IP =

[[$ ip == [0-9] @ ("" | [0-9]) @ ("" | [0-9]). [0-9] @ ("" | [0-9]) @ ( "" | [0-9]) [0-9] @. ( "" | [0-9]) @ ( "" | [0-9]). [0-9] @ ( "" | [0-9]) @ ("" | [0-9])]] && echo ตกลง || echo NOK สามารถแก้ไขด้านบนเพื่อ "กรอง" IP ที่ให้ไว้กับรูปแบบที่ต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.