Tôi có thể sử dụng biểu thức chính quy nào để khớp với địa chỉ IP?


35

Với grepcú pháp sau tôi muốn khớp tất cả địa chỉ IP trong một tệp (từ kshtập lệnh)

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

Vấn đề: Nó cũng khớp với các từ (IP) có nhiều hơn 4 octet:

1.1.1.1.1 

hoặc là

192.1.1.1.160

Làm cách nào tôi có thể khớp IP hợp lệ và chỉ địa chỉ IP với 4 octet? Tôi cũng có thể sử dụng Perl - một giải pháp cú pháp một dòng, nếu grepkhông hoạt động.


4
Nó sẽ phù hợp 999.999.999.999quá.
cYrus

4
Vì vậy, bạn chỉ muốn grep địa chỉ IPv4, phải không?
Arjan

5
Về mặt kỹ thuật, các địa chỉ IP như 192.1.4097hợp lệ và được chấp nhận bởi Linux glibc và Windows.
grawity

1
À, tôi chưa bao giờ biết ! ping 2130706433, trên OS X : PING 2130706433 (127.0.0.1): 56 data bytes.
Arjan

1
@Arjan: 0x7f.10177.1
grawity

Câu trả lời:


56

thử đi:

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

phù hợp với tất cả các biểu thức từ 0.0.0.0đến999.999.999.999

với

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

bạn sẽ chỉ nhận được địa chỉ IP

lưu ý:
trên solaris có lẽ egrep sẽ thực hiện công việc.


Tôi thử grep '\ b \ d {1,3} \. \ D {1,3} \. \ D {1,3} \. \ D {1,3} \ b' / etc / hosts nhưng tôi không nhận được bất cứ điều gì - :(
jennifer

1
@jennifer, bạn sẽ cần bật các biểu thức chính quy mở rộng: grep -E <pattern> <file>(hoặc, để chỉ in các trận đấu:grep -Eo <pattern> <file>
Arjan

như thế này ? grep -E '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / hosts
jennifer

3
@udo: Chà cái này khớp 1.1.1.1.1nhưng nó ẩn cái cuối cùng .1từ đầu ra, tôi không thể thấy nó có thể giúp được gì.
cYrus

1
Regrec của bạn không khớp với 10.0.0.1
Stefan Seidel

10

Cái này thế nào

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

Tốt đẹp! (Điều này cũng trả về 192.1.1.1.160192.1.1.1, điều mà tôi nghĩ là tốt cho người hỏi câu hỏi.)
Arjan

2
Nếu các địa chỉ IP phù hợp thực sự muốn, đây là loại giải pháp duy nhất có bất kỳ cơ hội nào gần hoàn thành. Khi tôi nhìn thấy câu hỏi, tôi chỉ nghĩ rằng "Tôi sẽ không chạm vào nó với một cột regrec tiêu chuẩn mười feet". Hãy cẩn thận, hãy cẩn thận ở khắp mọi nơi :-).
Daniel Andersson

5

Các

-w / --word-regexp 

gắn cờ để greplàm cho nó chỉ khớp trên các ranh giới từ, nghĩa là trận đấu của bạn phải được bao quanh bởi khoảng trắng hoặc bắt đầu / kết thúc ở đầu / cuối dòng!


5

Để chỉ tìm các kết quả khớp chính xác với 4 octet (không bao gồm những thứ như 1.1.1.1.1), hãy sử dụng:

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

Nó sẽ không bao giờ phát hiện các địa chỉ không phải IP. Biểu thức có thể phức tạp hơn để xác minh nhiều thứ hơn nhưng điều này sẽ hoạt động trong hầu hết các trường hợp. Nó sẽ không khớp với 0 trước vì 010.1.12.1 không phải là cách phổ biến để ghi địa chỉ 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

Một chút khó khăn, nhưng nó nên hoạt động:

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

Còn 127.000.000.001sau đó? ;-)
Arjan

Theo như tôi biết thì IP không có số không đệm.
cYrus

1
Hmmm, ping 127.000.000.001chắc chắn hoạt động trên máy Mac của tôi. Nhưng sau đó: tôi mới biết rằng thậm chí còn ping 2130706433mang lại kết quả rất giống nhau. :-) Rất tiếc, ping 00127.00000.00000.00001dịch sang 87.0.0.1. Lạ ... Có thể là bát phân? Vâng, chắc chắn là bát phân, vì vậy bạn đoán đúng về các số 0 hàng đầu tôi đoán.
Arjan

Có, 00127 (bát phân) = 87 (thập phân). Chắc chắn tất cả đều là IP hợp lệ, nhưng tôi đoán đó không phải là cách tiêu chuẩn để đại diện cho chúng. Dù sao đó không phải là yêu cầu của người hỏi.
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]) $ '

Phiên bản sửa đổi của câu trả lời của Arnaud B.

Biểu thức này sẽ không khớp địa chỉ IP với số 0 hàng đầu. ví dụ: nó sẽ không khớp với 192.168.1.01 Biểu thức này sẽ không khớp với các địa chỉ IP có nhiều hơn 4 octet. ví dụ: nó sẽ không khớp với 192.168.1.2.3


Điều này sẽ không phù hợp với 127.0.0.1.
Chris Charabaruk

0

Tôi đang sử dụng egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts để khớp địa chỉ IP ở đầu một dòng. Nó cũng có thể được sử dụng mà không cần ^cho phép khoảng trắng hoặc ký tự khác trước địa chỉ 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

Một phiên bản ngắn hơn của regex dài:

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

Vui lòng sử dụng grep -E hoặc egrep phù hợp với phiên bản HĐH của bạn


2
chào mừng tại superuser. Câu hỏi này đã có một số câu trả lời tốt. Để giúp mọi người hiểu sự khác biệt giữa họ, vui lòng chỉnh sửa câu trả lời của bạn và giải thích điều gì làm cho nó tốt hơn / khác biệt với những câu hỏi khác.
Máté Juhász

biểu thức này không tính đến các ips hợp pháp như 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}'=> không có kết quả
anneb 28/07/17


0

Biểu thức chính quy để khớp địa chỉ IP trong TCL

đặt "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

Đây là những gì làm việc cho tôi cho ksh và ksh93 trong 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])]] && tiếng vang OK | | echo NOK Có thể sửa đổi ở trên để "lọc" IP được cung cấp thành bất kỳ mẫu nào mong muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.