Мой ответ будет основан не на Java, поскольку это классический пример проблемы, которая может быть решена намного, намного проще.
Все, что вам нужно, это инструмент grep
. Если вы работаете в Windows, вы можете найти его здесь .
Предполагая, что ваши журналы находятся в файле log.txt
, решение вашей проблемы - один слой:
grep -hE --before-context 1 "^DB2[0-9]+E" log.txt > filtered.txt
Пояснение:
-h
- не печатать имя файла
-E
- поиск по регулярному выражению
--before-context 1
- это напечатает одну строку перед найденным сообщением об ошибке (это будет работать, если все ваши SQL-запросы находятся в одной строке)
^DB2[0-9]+E
- поиск строк, начинающихся с «DB2», имеющих некоторые цифры и заканчивающихся «E»
Выше выражение будет печатать каждую нужную строку в новом файле с именем filtered.txt
.
Обновление : после некоторого возни, мне удалось получить то, что нужно, используя только стандартные * nix утилиты. Осторожно, это не красиво. Конечное выражение:
grep -nE "^DB2[0-9]+" log.txt | cut -f 1 -d " " | gawk "/E$/{y=$0;print x, y};{x=$0}" | sed -e "s/:DB2[[:digit:]]\+[IE]//g" | gawk "{print \"sed -n \\\"\" $1+1 \",\" $2 \"p\\\" log.txt \"}" | sed -e "s/$/ >> filtered.txt/g" > run.bat
Пояснение:
grep -nE "^DB2[0-9]+" log.txt
- печатает строки, начинающиеся с DB2...
, а их номер строки начинается. Пример: * * тысяча сорок-две
6:DB20000I The SQL command completed successfully.
12:DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command.
19:DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command.
26:DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command.
34:DB20000I The SQL command completed successfully.
41:DB20000I The SQL command completed successfully.
47:DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command.
54:DB20000I The SQL command completed successfully.
cut -f 1 -d " "
- печатает только «первый столбец», то есть удаляет все после сообщения об ошибке. Пример: * * тысяча сорок восемь
6:DB20000I
12:DB21034E
19:DB21034E
26:DB21034E
34:DB20000I
41:DB20000I
47:DB21034E
54:DB20000I
gawk "/E$/{y=$0;print x, y};{x=$0}"
- для каждой строки, заканчивающейся буквой «E» (строка ошибки), выведите строку перед ней, а затем строку ошибки. Пример: * * тысяча пятьдесят-четырь
6:DB20000I 12:DB21034E
12:DB21034E 19:DB21034E
19:DB21034E 26:DB21034E
41:DB20000I 47:DB21034E
sed -e "s/:DB2[[:digit:]]\+[IE]//g"
- удаляет двоеточие и сообщение об ошибке, оставляя только номера строк. Пример:
6 12
12 19
19 26
41 47
gawk "{print \"sed -n \\\"\" $1+1 \",\" $2 \"p\\\" log.txt \"}"
- форматирует вышеуказанные строки для обработки sed и увеличивает номер первой строки на единицу. Пример:
sed -n "7,12p" log.txt
sed -n "13,19p" log.txt
sed -n "20,26p" log.txt
sed -n "42,47p" log.txt
sed -e "s/$/ >> filtered.txt/g"
- добавляет >> filtered.txt
к строкам для добавления в конечный выходной файл. Пример: * * тысяча семьдесят три
sed -n "7,12p" log.txt >> filtered.txt
sed -n "13,19p" log.txt >> filtered.txt
sed -n "20,26p" log.txt >> filtered.txt
sed -n "42,47p" log.txt >> filtered.txt
> run.bat
- наконец, печатает последние строки в пакетный файл с именем run.bat
После того, как вы запустите этот файл, требуемый контент появится в filtered.txt
.
Обновление 2 :
Вот еще одна версия, которая работает в Ubuntu (предыдущая версия была написана для Windows):
grep -nE "^DB2[0-9]+" log.txt | cut -f 1 -d " " | gawk '/E/{y=$0;print x, y};{x=$0}' | sed -e "s/:DB2[[:digit:]]\+[IE]//g" | gawk '{print "sed -n \""$1+1" ,"$2 "p\" log.txt" }' | sed -e "s/$/ >> filtered.txt/g" > run.sh
Две вещи не работали с предыдущей версией:
- по какой-то причине
gawk '/E$/'
не работал (он не распознал, что E находится в конце строки), поэтому я просто поставил /E/
, поскольку E
больше нигде не будет найдено.
- цитируя,
"
были преобразованы в '
для gawk, поскольку он не любит двойные кавычки; после этого, цитата внутри последнего выражения gawk была изменена