grep находит ipv4 в виде слов вместо строк

Pythonрешение:

образец входного файлаtest.csv:

A1,B1,C1,D1,E1,F1,A2,B2,C2,D2,E2,F2,A3,B3,C3,D3,E3,F3,A4,B4,C4,D4,E4,F4
G1,H1,I1,J1,K1,L1,G2,H2,I2,J2,K2,L2,G3,H3,I3,J3,K3,L3,G4,H4,I4,J4,K4,L4

фрагмент _на _6.pyскрипт:

import sys, csv
with open(sys.argv[1], 'r') as fh:  # opening csv file
    reader = list(csv.reader(fh))   # reader object which will iterate over lines in the given csvfile
    cnt = len(reader[0])//6         # number(count) of slices
    for i in range(cnt):
        for l in reader:
            print(','.join(l[i*6:6*(i+1)]))  # outputting each slice from each line consecutively

Использование:

python slice_on_6.py test.csv

Выход:

A1,B1,C1,D1,E1,F1
G1,H1,I1,J1,K1,L1
A2,B2,C2,D2,E2,F2
G2,H2,I2,J2,K2,L2
A3,B3,C3,D3,E3,F3
G3,H3,I3,J3,K3,L3
A4,B4,C4,D4,E4,F4
G4,H4,I4,J4,K4,L4
0
07.09.2019, 20:45
4 ответа

Удалите ^и $из команды и используйте флаг -oкоманды grep, т.е.:

grep -Eo '(^| )(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($|[[:space:]])'

Пример:

echo 'some text 198.54.34.6 and test' | grep -Eo '(^| )(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($|[[:space:]])'

вывод:

 198.54.34.6

Это даст пробелы, также попробуйте удалить их, используя tr, например command1 | tr -d " ".

4
28.01.2020, 02:13

^и $совпадают соответственно в начале и конце строки, поэтому строки с этими IP-адресами совпадают только в том случае, если IP-адрес находится как в начале, так и в конце строки, то есть если IP-адрес — это вся строка.

Теперь, если вы хотите сопоставить строки, содержащие IP-адрес целиком слово , где слова пусты -с разделителями, вы можете использовать:

d='[01234567890]'
n="($d|[123456789]$d|1$d$d|2[01234]$d|25[012345])"
grep -E "(^|[[:blank:]])$n\.$n\.$n\.$n([[:blank:]]|\$)" ip.txt

(здесь также замена [0-9]на [0123456789], поскольку [0-9]часто соответствует гораздо большему, чем просто 0123456789 ).

Обратите внимание, что grepвыводит совпадающие строки . Если вы хотите выводить только части строк, вам нужно использовать такие вещи, как sedили perlвместо (потоковых редакторов ), или использовать некоторые не -стандартные расширения некоторых grepреализации, такие как -oGNU grep.

Здесь используется отрицательный взгляд -вокруг операторов ((?<!\H), что означает «при условии, что ему не предшествует не -пробел» , (?!\H)то же самое, но взгляд вперед, а не назад, (?1)вызывает RE в первой группе (...), все perl -подобные операторы включены с-P:

grep -Po '(?<!\H)(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)(?!\H)' ip.txt

Что было бы эквивалентно:

perl -lne 'print for
  /(?<!\H)(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)(?!\H)/g'
3
28.01.2020, 02:13

Это регулярное выражение захватывает IP-адрес и является довольно точным регулярным выражением для IPv4-адресов, grep -Pвключает механизм регулярных выражений PCRE и -oвозвращает только соответствующий текст:

grep -Po '\b((?:25[0-5]|[2][0-4][0-9]|[1][0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|[2][0-4][0-9]|[1][0-9]{2}|[1-9][0-9]|[0-9])\b' ip.txt

Объяснение этого регулярного выражения см. здесь:https://regexr.com/4kjg4

25[0-5]          | # 250 - 255 
[2][0-4][0-9]    | # 200 - 249 
[1][0-9]{2}      | # 100 - 199 
[1-9][0-9]       | #  10 - 99
[0-9]            | #   0 - 9
1
28.01.2020, 02:13

Чтобы распечатать только IPv4, вы можете извлечь то, что совпадает с опцией -oдля grep.

В качестве более простого примера вы можете сделать:

$ echo "this is a simple test to extract 123.234.34.5 as an IP" | 
       grep -o '[0-9.]*'

123.234.34.5

Но это не будет точно соответствовать одному IPv4.

Для сопоставления IP-адреса с регулярным выражением несколько сложно. Регулярное выражение не понимает числовые диапазоны, только текст. Мы можем сопоставить одно числовое значение 0 -255 с (регулярным выражением, которое игнорирует пробелы и комментарии):

25[012345]                       | # the numers 250 - 255 or
2[01234](?P<digit>[0123456789])  | # 200 - 249 or
1(?&digit){2}                    | # 100 - 199 or
#0?                                 # Allow leading zero
[1-9](?&digit)                   | #  10 -  99 or
#0{0,2}                             # Allow leading zeros
(?&digit)                          #   0 - 9

Удалите комментарии к первому столбцу, чтобы включить ведущие нули.

Чтобы избежать повторения [0-9], использовать явные числовые диапазоны (, избегать сопоставления чисел на других языках )и давать имя каждой совпадающей группе, мы можем использовать «Именованные группы захвата» из PCRE :

. ]
(?P<byte>                             # Define this as one full byte value.
25[012345]                          | # the numers 250 - 255 or
2[01234](?P<digit>[0123456789])     | # 200 - 249 or
1(?&digit){2}                       | # 100 - 199 or
#0?                                    # Allow leading zero
[1-9](?&digit)                      | #  10 -  99 or
#0{0,2}                               # Allow leading zeros
(?&digit)                             #   0 - 9
)                                     # close one full byte definition

Затем нам просто нужно повторить использование определения байта с ведущей точкой (\.(?&byte)){3}еще три раза и некоторыми начальными и конечными маркерами, как показано в этой ссылке

Начальный и конечный маркеры могут быть более простыми «границами слов» (\b), если это то, что необходимо, как показано в этой другой ссылке

В оболочке с регулярным выражением grep PCRE команда может быть записана как:

$ grep -oP '(?xm)(?<=^|[^01234567890.])(?P<byte>25[012345]|2[01234](?P<digit>[0123456789])|[01]?(?&digit){1,2})(\.(?&byte)){3}(?=[^01234567890.]|$)' <<<"$a"
1.2.3.4
11.22.33.44
123.234.34.5
1.1.192.168
123.234.34.123
123.234.34.123
1.2.3.255
255.255.255.255
1.1.168.192
1.14.2.90
1.2.3.4

Учитывая, что тестовая строка содержит:

$ a='1.2.3.4
11.22.33.44
123.234.34.5
1.1.192.168
text 123.234.34.123 more text
text123.234.34.123more text
1.2.3.255
1.2.3.256
255.255.255.255
256.2.3.4
1123.234.34.123
123.234.34.1235
.123.234.34.123
123.234.34.123.
not 1.1.168.192 in 1.1.168.192.in-addr.arpa.
not 1.14.2.90 in xserver-common_1.14.2.901-2_all.deb
1.2.3.4'
2
28.01.2020, 02:13

Теги

Похожие вопросы