
У меня есть файл со следующими входными данными. Числа, разделенные точками, представляют адреса. Любое число в адресе может состоять из одной или нескольких цифр, как показано ниже:
[112.112.112.112;3.3.3.3;44.44.44.44]
[6.6.6.6;17.17.17.17;88.88.88.88]
Я хочу извлечь каждый адрес без точек с запятой и скобок (адреса разделяются точкой с запятой ;
) и вставить каждый адрес в строку нового файла, чтобы получить следующий вывод:
112.112.112.112
3.3.3.3
44.44.44.44
6.6.6.6
17.17.17.17
88.88.88.88
В качестве первого шага я попробовал извлечь адреса с помощью grep следующим образом:
grep -E '\d+\.\d+\.\d+\.\d+' myfile.txt > newfile.txt
Но он ничего не печатает.
решение1
Расширенное регулярное выражение( -E
или egrep
) не знает о \d
. Используйте -P
, как предложил @Alexander, или используйте -E
с [0-9]
или [[:digit:]]
вместо этого.
Добавить -o
, чтобы выбрать только совпадения вместо целых совпадающих строк. Это также разобьет отдельные совпадения на новые строки.
grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' myfile.txt
или
grep -Eo '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' myfile.txt
с использованиемPerl Регулярное выражение( -P
или pgrep
):
grep -Po '\d+\.\d+\.\d+\.\d+' myfile.txt
Если вы измените +
на , *
вы также можете использоватьБазовое регулярное выражение:
grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' myfile.txt
решение2
Заменить -E
на -P
и добавить -o
:
grep -P -o '\d+\.\d+\.\d+\.\d+' myfile.txt
решение3
С использованием awk
:
awk 'NF' RS='[][;]' infile
Или tr
, если вас не смущает первая пустая строка:
tr -s '];[' '\n' <infile
решение4
grep
это своего рода излишество для этой задачи. tr
достаточно:
$ < input.txt tr -d '[]' | tr ';' '\n' | sort -u
Часть sort -u
удаляет дублирующиеся адреса.