grep with streaming data
in.txt
WARNING:
....
тут очень очень длинный файл
....
последняя строчка: NOTE
как такой файл грепать? полностью загружать его в память и потом полностью его вываливать в ответ?
скорей нада уметь искать в нескольких соседних строчках
а эта задача уже легко решается
например с помощью sed
работать с потоком в котором могут встретиться символы \n etcЭто перевод строки что ли?
grep работает с потоком нормально, обрабатывает построчно.
Т.е. на несколько строк не будет матчиться. Это можно изменить, кажется, но по умолчанию так. Кроме того, если надо на несколько строк матчить, то с жадными регулярными выражениями могут проблемы быть.
как такой файл грепать? полностью загружать его в память и потом полностью его вываливать в ответ?а как он грепает очень длинные строчки?
Я просто sed плохо знаю. Читаю пока мануалы, но если ктото уже напишет пример скрипта буду очень признателен.
как сделать с помощью sed'a не совсем понимаюну поищи примеры в гугле
или ман почитай
смысл там типа такого:
смотрим строчку, если буфер пустой и строчка содержит начало поиска, то добавляем строчку в буфер
если буфер пустой и строчка не содержит начало поиска - игнорируем ее
если буфер не пустой и строчка содержит конец поиска - выплевываем рузельтат, очищаем буфер
если буфер не пустой и строчка не содержит конец поиска - добавляем ее в буфер
Да именно так и надо вывалить весь кусок в ответ, по структуре файла знаю что этот варнинг займет примерно 3-4 строкиТы неправильно понял. Если будет 10 таких варнингов, то тебе вывалится всё начиная от начала первого и заканчивая последней строчкой последнего. Причём и то, что посередине - тоже.
Вообще, grep выводит не то, что он поматчил, а ту строчку, в которой он это поматчил.
Такое поведение, какое тебе надо, можно достаточно просто сделать с помощью sed или awk.
а как он грепает очень длинные строчки?и всё же?
и всё же?Учитывая, что ему строчку нужно всю помнить, т.к. заранее не известно о том, поматчится она или нет, то он её в память загружает.
А вообще в теории матчить можно и так, что каждый просмотренный байт можно забывать. Но если выводить надо, то придётся запоминать.
смотрим строчку, если буфер пустой и строчка содержит начало поиска, то добавляем строчку в буфересли буфер пустой и строчка не содержит начало поиска - игнорируем ееесли буфер не пустой и строчка содержит конец поиска - выплевываем рузельтат, очищаем буфересли буфер не пустой и строчка не содержит конец поиска - добавляем ее в буферэт какой-то изврат. Неужели нет подобного струмента, который рассматривает перенос строки как обычный символ?
эт какой-то изврат. Неужели нет подобного струмента, который рассматривает перенос строки как обычный символ?ну как бы можно это запрограммить например на перле
стандартных консольных утилит не знаю
Неужели нет подобного струмента, который рассматривает перенос строки как обычный символ?можешь в этом потоке заменить все переводы строк на что-нить особенное и искать в этом грепом.
можешь в этом потоке заменить все переводы строк на что-нить особенное и искать в этом грепом.tr кстати с этим отлично справляется
| tr "\n" "@"
по-хорошему, сперва заменить переводы строк на собачек, а собачек задвоить, потом обработать, потом сдвоенных собачек сделать одиночными, а несдвоенных - переводами строк
Написал на sed'e, тему можно закрывать. всем спасибо за ответы.
Написал на sed'e, тему можно закрывать. всем спасибо за ответы.ну покажи красоту
эт какой-то изврат. Неужели нет подобного струмента, который рассматривает перенос строки как обычный символ?Никакого изврата. Инструмены есть. И тот же grep это умеет, в том числе выводить только поматченный образец. Я уже писал об этом. И о проблемах такого решения тоже.
all.sh:
#!/usr/bin/bash
base="$@"
echo $base
cat $base | sed -f 2.scr | sed -f 3.scr | sed -f 4.scr > res.txt
2.scr:
# preprocess file...
/^ *$/d
/ The SAS System *.*2008/d
#kill header
1,/NOTE:/{
/NOTE:/!d
}
#kill all notes
/NOTE:/,/WARNING:/{
/WARNING:/!d
}
#kill tail
/NOTE:/,${
d
}
s/WARNING/\
WARNING/g
3.scr:
/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g
4.scr:
/^$/d
Почему то все вместе в одном файле работает неверно, не стал разбираться ибо был ограничен во времени решения задачи, просто разбил на независимые файлы.
s/WARNING/\что это?
WARNING/g
*.*что это?
Оставить комментарий
Gunsleader
под streaming data я понимаю парсер который за один проход(One-pass) поток большой - обратный проход неприемлем)Как заставить grep(или какие аналоги посоветуете вроде греп one-pass? ) работать с потоком в котором могут встретиться символы \n etc
in.txt
WARNING: 123 \n
NOTE: 123
grep ^WARNING:.*NOTE: in.txt >res.txt
не находит ничего(т.к. смотрит построчно)