Как получить текст от диапазона дат с помощью grep/sed в файле крупного текста?

У меня есть большой текст файла (почти 3 ГБ) - это - файл журнала. Я хочу получить строки текста, которые соответствуют диапазону дат из этого файла с 13 июля до 19 июля. Мой формат журнала:

2016-07-12 < ?xml version>
2016-07-13 < ?xml version>
2016-07-18 < ?xml version>
2016-07-18 < ?xml version>
2016-07-19 < ?xml version>
2016-07-20 < ?xml version>
sample text sample text
sample text sample text
sample text sample text
2016-07-20 < ?xml version>
sample text sample text
2016-07-20 < ?xml version>

таким образом после grep/sed это должно быть произведено как это:

2016-07-13 < ?xml version>
2016-07-18 < ?xml version>
2016-07-18 < ?xml version>
2016-07-19 < ?xml version>

Как я могу получить это?

8
задан 20 July 2016 в 04:52

5 ответов

С grep, если Вы знаете количество строк, Вы хотите Вас, может использовать опцию -A контекста распечатать строки после шаблона

grep -A 3 2016-07-13 file

, который даст Вам строку с 13.07.2013 и следующие 3 строки

с sed, можно использовать даты для разграничивания как это

sed -n '/2016-07-13/,/2016-07-19/p' file

, который распечатает все строки от первой строки с 13.07.2016 до и включая первую строку с 19.07.2016. Но это предполагает, что у Вас есть только одна строка с 19.07.2016 (она не распечатает следующую строку). Если существует несколько строк, используют следующую дату вместо этого и используют d для удаления вывода из него

sed -n '/2016-07-13/,/2016-07-20/{/2016-07-20/d; p}' file
12
ответ дан 23 November 2019 в 05:21

Этот простой grep один лайнер будет достаточно:

grep -E ^2016-07-1[3-9] filename

Работы приятно тут и там не потребность в sed :)

Ссылки:

10
ответ дан 23 November 2019 в 05:21

awk решение:

$ awk '/^2016-07-13.*/,/2016-07-19.*/'  input.txt                                   
2016-07-13 < ?xml version> 
2016-07-18 < ?xml version> 
2016-07-18 < ?xml version> 
2016-07-19 < ?xml version> 

В основном печать любая строка от той, которая запускается с 2016-07-13 к тому, который запускается с 2016-07-19

4
ответ дан 23 November 2019 в 05:21

Вы могли сделать это на шагах. Найдите количество первой строки, соответствующей Вашему стартовому шаблону. Найдите количество последней строки, соответствующей Вашему конечному шаблону. Затем извлеките тест между этими двумя строками. Это может быть сделано следующим образом.

grep -n 2016-07-13 bigtextfile | head -1
grep -n 2016-07-19 bigtestfile | tail -1
# Say the first number is 1234 and the second 5678, then use...
awk 'NR>=1234 && NR<=5678' bigtestfile > rangeoftext

Это могло быть сделано все в awk, команда кроме шагов может помочь следовать. В awk НОМЕР переменной является текущим номером строки, и так как никакое действие не было указано после шаблона (НОМЕР> =1234 & & NR< =5678), действие по умолчанию должно распечатать строки это в том диапазоне.

3
ответ дан 23 November 2019 в 05:21

Все другие текущие ответы полагаются на то, что записи файла журнала отсортированы хронологически или то, что диапазон дат может быть подобран легко с регулярными выражениями. Если Вы хотите более универсальное решение, мы должны сделать еще некоторое программирование.

Я представляю этот сценарий AWK GNU:

#!/usr/bin/gawk -f
BEGIN {
    starttime = mktime(starttime)
    endtime = mktime(endtime)
}

func in_range(n, start, end) {
    return start <= n && n < end
}

match($0, /^([0-9]{4})-([0-9]{2})-([0-9]{2})\s/, m) &&
    in_range(mktime(m[1] " " m[2] " " m[3] " 00 00 00"), starttime, endtime)

Вы предоставляете запуск и время окончания через переменные starttime и endtime в формате это mktime понимает (YYYY MM DD hh dd ss). Таким образом Вы работаете awk управляйте как так, предполагая, что вышеупомянутый сценарий Awk находится в исполняемом файле filter-log-dates.awk в текущем рабочем каталоге и файле журнала mylog.txt:

./filter-log-dates.awk -v starttime='2016 07 13 00 00 00' -v endtime='2016 07 20 00 00 00' mylog.txt

Обратите внимание, что время окончания эксклюзивно, т.е. действительные записи журнала должны иметь метку времени перед временем окончания.

Если Ваш формат метки времени отличается, можно корректироваться, регулярное выражение передало match функционируйте для удовлетворения ему.

4
ответ дан 23 November 2019 в 05:21

Другие вопросы по тегам:

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