У меня есть 90 гигабайт данных, извлеченных из 13,5 терабайт.
Я попробовал sort -u | uniq
использовать данные, извлеченные из 13,5 ТБ данных системного журнала.
Были обнаружены некоторые некорректные данные, поэтому я повторно запустил синтаксический анализ с помощью awk и «увидел» следующее:
awk -F, '!seen[$1]++' inputfile > outputfile
Это оказалось наиболее эффективным по времени способом, но также включало некоторые неправильно сформированные данные... возможно, есть неправильно сформированные записи журнала или в сортировке uniq'ing и awk'ing некоторые строки были испорчены. Мне все равно, есть ли более/лучший способ парсинга исходных данных, поскольку у меня достаточно большой размер выборки - то есть потеря небольшого количества данных из 13,5T допустима.
На каждую действительную строку приходится 3 IP-адреса.
Поскольку в IP-адресе три точки, мне нужно что-то, что будет анализировать только строки, содержащие 9 «.».
решение1
Давайте возьмем это в качестве тестового файла:
$ cat testfile
1.2.3.4 5.6.7.8 9.10.11.12 Keep
1.2.3.4 5.6.7.8 9.10.11 Bad: Missing 1
1.2.3.4 5.6.7.8 9.10.11.12. Bad: Extra period
Использование grep
Чтобы выбрать строки, содержащие ровно девять точек:
$ grep -E '^([^.]*\.){9}[^.]*$' testfile
1.2.3.4 5.6.7.8 9.10.11.12 Keep
[^.]*\.
соответствует любому количеству символов, не являющихся точкой, за которыми следует ([^.]*\.){9}
соответствует ровно девяти последовательностям из нуля или более символов, не являющихся точкой, за которыми следует точка. ^
В начале требуется, чтобы регулярное выражение сопоставлялось с началом строки. Означает [^.]*$
, что между концом девяти последовательностей и концом строки разрешены только символы, не являющиеся точкой.
Использование sed
$ sed -En '/^([^.]*\.){9}[^.]*$/p' testfile
1.2.3.4 5.6.7.8 9.10.11.12 Keep
Опция -n
сообщает sed не печатать, пока мы явно не попросим его об этом. p
Следующее регулярное выражение явно просит sed печатать те строки, которые соответствуют регулярному выражению.
Использование awk
$ awk '/^([^.]*\.){9}[^.]*$/' testfile
1.2.3.4 5.6.7.8 9.10.11.12 Keep
Или, используя возможность awk определять символ для разделения полей (спасибо:Джефф Шаллер):
$ awk -F. 'NF==10' testfile
1.2.3.4 5.6.7.8 9.10.11.12 Keep