Я знаю, как grep
найти в файле все строки, содержащие простую строку:
cat my_log.log | grep 'Completed 200 OK in'
Это возвращает результаты, подобные следующему:
various info... Completed 200 OK in 250ms various info...
various info... Completed 200 OK in 112ms various info...
various info... Completed 200 OK in 1000ms various info...
various info... Completed 200 OK in 6000ms various info...
various info... Completed 200 OK in 33ms various info...
various info... Completed 200 OK in 100ms various info...
Я хотел бы сделать еще один шаг и вернуть только строки, в которых миллисекунды (мс) равны над 1000.
Возможно ли это с помощью grep? В других сообщениях предлагается использовать sed
, но мне любопытно, можно ли это сделать с помощью grep
.
Конечно
Команда grep поставляется с параметром -E
, который включает расширенные регулярные выражения в вашем шаблоне.
Тогда вам просто нужно найти 4-значное значение с помощью регулярного выражения [0-9]{4}
cat my_log.log | grep -E "Completed 200 OK in [0-9]{4}ms"
Если вам нужно 4 или более цифр, просто используйте диапазон {4,}
вместо {4}
cat my_log.log | grep -E "Completed 200 OK in [0-9]{4,}ms"
Grep по умолчанию использует регулярные выражения, но -E
включает «расширенные регулярные выражения», где вам нужно избежать меньшего количества/других вещей: grep '.\{4\}'
и grep -E '.{4}'
эквивалентны.
Ха... Я этого не знал - я всегда использовал -E
при работе с grep и регулярными выражениями... Спасибо за это @BenjaminW.
Ставь cat
, не надо.
Это напечатает строку, в которой ms равно 1000 мс, а не только тогда, когда оно превышает 1000, как указано в вопросе, и вы не можете легко использовать этот подход с регулярным выражением для произвольных чисел.
Правильный способ сделать это - awk как для регулярного выражения, так и для арифметического сравнения, например. с GNU awk для третьего аргумента для соответствия():
$ awk 'match($0,/Completed 200 OK in ([0-9]+)/,a) && (a[1] > 1000)' file
various info... Completed 200 OK in 6000ms various info...
$ awk 'match($0,/Completed 200 OK in ([0-9]+)/,a) && (a[1] >= 1000)' file
various info... Completed 200 OK in 1000ms various info...
various info... Completed 200 OK in 6000ms various info...
$ awk 'match($0,/Completed 200 OK in ([0-9]+)/,a) && (a[1] >= 112)' file
various info... Completed 200 OK in 250ms various info...
various info... Completed 200 OK in 112ms various info...
various info... Completed 200 OK in 1000ms various info...
various info... Completed 200 OK in 6000ms various info...
или если у вас нет GNU awk, то с любым awk:
$ awk '{ms=$0} sub(/.*Completed 200 OK in /,"",ms) && (ms+0 > 1000)' file
various info... Completed 200 OK in 6000ms various info...
Его не следует решать ни с помощью grep, ни с помощью sed, поскольку ни один из них не поддерживает арифметические операции, а попытки выполнить числовое сравнение с регулярными выражениями чрезвычайно громоздки и подвержены ошибкам. Просто используйте инструмент, который может выполнять арифметические действия, например. хорошо