Таким образом, открывание файла с помощью cat
и последующее использование grep
для получения совпадающих строк только уводит меня, когда я работаю с определенным набором журналов, с которым я имею дело. Нужен способ сопоставления линий с шаблоном, но только для возврата части строки после соответствия. Доля до и после матча будет постоянно меняться. Я играл с использованием sed
или awk
, но не смог выяснить, как отфильтровать строку, чтобы либо удалить часть до матча, либо просто вернуть часть после матча, либо сработает. Это пример строки, которую мне нужно отфильтровать:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
Часть, в которой я нуждаюсь, - это все, что после "остановлено".
Подоплекой этого является то, что я могу узнать, как часто что-то глохнет:
cat messages | grep stalled | wc -l
Что мне нужно сделать, это выяснить, сколько раз определенный узел останавливался (на что указывает часть перед каждым двоеточием после «остановленного»). Если я просто grep для этого (то есть 20 :), он может вернуть строки, которые имеют мягкие сбои, но нет остановок, что не помогает мне. Мне нужно отфильтровать только остановленную часть, чтобы я мог найти конкретный узел из тех, которые остановились.
По сути, это система freebsd со стандартными утилитами ядра GNU, но я не могу установить ничего, чтобы помочь.
источник
sed
решение и не обрабатывайте пробелы специально.Ответы:
Каноническим инструментом для этого будет
sed
.Детальное объяснение:
-n
означает не печатать ничего по умолчанию.-e
сопровождается командой sed.s
команда замены шаблона^.*stalled:
соответствует шаблону, который вы ищете, плюс любой предыдущий текст (.*
имеется в виду любой текст, с инициалом,^
указывающим, что совпадение начинается в начале строки). Обратите внимание, что еслиstalled:
в строке происходит несколько раз, это будет соответствовать последнему вхождению.stalled:
, заменяется пустой строкой (т.е. удаляется).p
означает печатать преобразованную строку.Если вы хотите сохранить соответствующую часть, используйте обратную ссылку:
\1
в заменяемой части обозначается то, что находится внутри группы\(…\)
в шаблоне. Здесь вы можете написатьstalled:
снова в запасной части; эта функция полезна, когда шаблон, который вы ищете, является более общим, чем простая строка.Иногда вы захотите удалить часть строки после матча. Вы можете включить его в совпадение, добавив
.*$
в конце шаблона (любой текст,.*
за которым следует конец строки$
). Если вы не поместите эту часть в группу, на которую вы ссылаетесь в тексте замены, конец строки не будет в выводе.В качестве дополнительной иллюстрации групп и обратных ссылок эта команда меняет местами часть перед совпадением и деталь после совпадения.
источник
sed … <messages
, поскольку хотите обрабатывать данные из файла. Для того, чтобы воздействовать на данные , полученные с помощью другой команды, вы бы использовать трубу:somecommand | sed …
.sed 's/^.*stalled//'
поскольку-r
он специфичен для Linux и не работает на других системах, таких как macOS, и здесь вы не получаете никакой выгоды от него.Другой канонический инструмент, который вы уже используете
grep
:Например:
Имеет тот же результат, что и второй вариант Жиля:
-o
Флаг возвращает--only-matching
часть выражения, поэтому не вся линия, - конечно - обычно делается Grep.Чтобы убрать «stalled:» из вывода, мы можем использовать третий канонический инструмент, cut:
Команда
cut
использует разделитель:
и печатает поле 2 до конца. Конечно, это вопрос предпочтений, ноcut
синтаксис, который я нахожу, очень легко запомнить.источник
-o
опции! Я хотел указать, чтоgrep
не распознает символ\n
новой строки, поэтому ваш первый пример соответствует только первомуn
символу. Например,echo "Hello Anne" | grep -o 'A[^\n]*'
возвращает строкуA
. Однакоecho "Hello Anne" | grep -o 'A.*'
возвращает ожидаемоеAnne
, поскольку.
соответствует любому символу, кроме новой строки.cut
разделителя-d':'
удаляются @poige. Мне легче запоминать с помощью кавычек, например, с помощью-d' '
или-d';'
.-f 2
. Серьезно, почему бы и нет?;
а не двоеточие,:
будет интерпретирован по-разному, если не будет заключен в кавычки. Конечно, это логичное поведение, но все же мне нравится полагаться на мышечную память. Я не люблю цитировать разделитель один раз, но не в другой раз. Просто личные предпочтения, как я уже говорил: легче запомнить..*
необходим, хорошо работал для меня:cat filename | grep 'Return only this line xyz text' | grep -o 'xyz.*'
возвращаетсяxyz text
Я имел обыкновение
ifconfig | grep eth0 | cut -f3- -d:
брать этои сделать так, чтобы это выглядело так
источник
cat /sys/class/net/*/address
, анализ не требуется.Еще один канонический инструмент, который вы рассмотрели,
awk
можно использовать со следующей строкой:Детальное объяснение:
-F
определяет разделитель для строки, т. е. «остановлен». Все до разделителя адресовано$1
и все после с$2
./reg-ex/
Ищет подходящее регулярное выражение, в этом случае "остановлено".{print $<n>}
- печатает столбец n. Поскольку ваш разделитель определен как остановленный, все после остановленного считается вторым столбцом.источник