LINUX.ORG.RU

Sed

 , ,


1

2

Доброго всем здравия! Возникло желание обуздать sed, но вот никак не получается. По простым операциям в принципе все понятно, сложности начинаются когда нужно использовать разные условия в одном блоке sed. Например, нужно найти стоку содержащую два «условия» и отобразить цифры после этих условий с выводом в две строки. Мне понадобилось узнать значения TX и RX на интерфейсе eth0 и вот что я нашел:

ifconfig eth0 | sed '/\s*[RT]X bytes:/s/[: ]\+/\n/g;/^[0-9]\+\n/P;D'
но, честно Вам сказать, все что находится после «sed» для меня практически не понятно, например почему в начале используется «/\s*» за что отвечает «*» в данном примере? В общем, если есть желающие разжевать синтаксис данного примера, то буду очень благодарен. З.Ы. ссылками на литературу про sed прошу не кормить - сыт по горло.

Ответ на: комментарий от beastie

Спасибо, я так понимаю использование \s в этом примере не обязательно, а что по поводу .../s/[: ]\+/\n/g;/^[0-9]\+\n/P;D'? Что в этой части кода происходит? зачем там +?

Sherman ()
Ответ на: комментарий от Sherman

/\s*[RT]X bytes/s/[: ]\+/\n/g;/^[0-9]\+\n/P;D

Чтобы не заниматься извращениями, перепишем расширенными регулярками (sed -r): /\s*[RT]X packets/s/[: ]+/\n/g;/^[0-9]+\n/P;D

/\s*[RT]X bytes/s/[: ]+/\n/g; - в строках содержащих RX bytes или TX bytes заменить произвольное > 1 кол-во пробелов и : подряд на возврат каретки

/^[0-9]+\n/P; - после чего найти строки где осталось только число и вывести

D - и удалить все выжившее

Balantay ()
Ответ на: комментарий от Balantay

спасибо. соответственно все это можно укоротить до такого вида?

sed '/[RT]X bytes/s/[: ]\+/\n/g;/^[0-9]/P;D'
еще вопрос /s/ выступает как «И» или «ДАЛЕЕ»?

Sherman ()
Ответ на: комментарий от Sherman

Укоротить можно.

И не так, и не так. Команды sed имеют формат ШАБЛОН/КОМАНДА; , в данном случае шаблон - это [RT]X bytes, а команда - s/[: ]\+/\n/g.

Balantay ()
Ответ на: комментарий от Balantay

Кстати, не особо внимательно читал обе команды, укоротить так нельзя.

$(echo "DMRX packets 5689fd54^^^" && ifconfig eth0) | sed '/[RT]X packets/s/[: ]\+/\n/g;/^[0-9]/P;D
5689fd54^^^
5317994
5807620733
4435659
530463480
$(echo "DMRX packets 5689fd54^^^" && ifconfig eth0) |  sed -r '/\s*[RT]X packets/s/[: ]+/\n/g;/^[0-9]+\n/P;D'
5317994
5807620733
4435659
530463480

Balantay ()
Ответ на: комментарий от beastie

\ перед + - это ж вроде синтаксис не-расширенных регулярок. Очень редко ими пользуюсь, поэтому не уверен, и не понимаю, почему люди не юзают везде sed -r.

Balantay ()
Ответ на: комментарий от Balantay

Все, понял, спасибо. Вот еще вопрос, правильно ли я понимаю, что в этом блоке

s/[: ]\+/\n/g
+ не нужен, потому как в конце стоит g? ведь g выполняет «бесконечное» количество повторений?

Sherman ()
Ответ на: комментарий от Balantay

спасибо большое за Ваши ответы, которые внесли не мало ясности.

Sherman ()
Ответ на: комментарий от Sherman

За тем, что это правильный ответ. Парзить выхлоп ifconfig — неблагодарное занятие, когда всё уже есть готовое и доступное через /proc или sysctl.

beastie ★★★★★ ()
Ответ на: комментарий от beastie

понятно, что это сродни анонизму, но это просто пример. вопрос был задан по теме sed'a и только его. это можно сделать и awk и grep'oм, но интересовал именно синтаксис sed'a и не более того.

Sherman ()
Ответ на: комментарий от Sherman

затем что для каждой задачи нужно использовать адекватный инструмент, а для поставленной задачи им является именно awk, как это можно легко видеть из сравнения наглядности и простоты двух представленных решений

вот ей-богу, изучат один sed (и так многие делают, и не только на лоре), а потом применяют его абсолютно везде, где надо и где не надо, просто потому что больше ничего не умеют, а в результате получаются мухобойные регекспы, которые хрен разберет даже сам автор уже через неделю

sed — мощный и сложный инструмент более всего пригодный для условного изменения текста

awk — гораздо проще и нагляднее, очень хорош для вычленения некоторых участков из массива текста

anonymous ()
Ответ на: комментарий от beastie

как любого новичка в sed'e меня просто пугает невменяемое количество слешей и прочих разделителей:) не могу, так сказать, сконцентрироваться. обязательно посмотрю, спасибо.

Sherman ()
Ответ на: комментарий от anonymous

Some people, when confronted with a problem, think «I know, I'll use regular expressions.» Now they have two problems.

;)

beastie ★★★★★ ()
Ответ на: комментарий от anonymous

я даже спорить с Вами не стану, придет время и я буду разбирать awk. Вы безусловно правы в том что awk легче и нагляднее, но порой нужен sed. Пока что я хочу понять sed, за все сразу хвататься не хочется, ибо дело это гиблое. P.S. в данный момент я очень часто пользуюсь awk и grep из-за простоты и ничего против этих утилит/языков нужное подчеркнуть не имею.

Sherman ()
Ответ на: комментарий от Balantay

дело именно в их количестве и последовательности. а # или % не имеет значения)

Sherman ()
Ответ на: комментарий от Sherman

две ошибки:

1) начинать изучение лучше с более простого инструмента, т.е. с awk, а не с sed'а, тем более, что awk в реальной практике требуется чаще

2) учиться sed'у хорошо бы на подходящих заданиях, т.е. на таких, где требуется именно как-то исправить некий массив текста, хотя бы для того, чтобы выработать правильный навык выбора адекватного инструмента; кстати, то что подходящее задание для изучения sed'а не так легко придумать, и поэтому используются неподходящие для этого задания, где правильнее использовать другие инструменты, как раз и говорит о том, что область применения sed'а ну очень уж узка, рискну сказать, что узка она до такой степени, что нет смысла вообще заранее его изучать — все равно реальная потребность будет возникать очень редко, что скорее всего уже забудешь к тому моменту все что наизучал, легче изучать его при решении конкретных задач

anonymous ()
Ответ на: комментарий от beastie

regexp — это finite state machine. Как только ты это поймёшь — всё станет сразу ясно.

А у вас в Берлине сейчас не модно давать ссылки на нормальные источники, например на Ахо и Ульмана, где всё разжёвано так, что и ежу ясно?
finite state machine - конечный автомат, переводится так уже много десятков лет. Или тебе что-то мешает пользоваться русским языком? А ещё модератор...

ABW ★★★★★ ()

Возьми какой-нибудь онлайновый тестировщик регулярных выражений, у них обычно шпаргалка на видном месте висит, а заодно и потестить можно.
https://regex101.com/ например.

thesis ★★★★★ ()
Ответ на: комментарий от ABW

ради справедливрсти надо отметить, что перевод этот не слишком удачен. Английский вариант лучше. Машина с конечным числом состояний — отражает суть модели, конечный автомат — нет.

Вообще научная заимствованная терминология оставляет желать лучшего во всех отраслях. Например в физике термин квантовая спутаннность, иногда запутанность — это какой то финиш. Там явно по смыслу должна быть «связь», «корреляция». И эти ваши *ученые* еще при этом пытаются доказать, что они понимают то о чем говорят, а не просто пытаются распилить бюджет.

xlsparse ()
Ответ на: комментарий от xlsparse

Машина с конечным числом состояний — отражает суть модели, конечный автомат — нет.

https://ru.wikipedia.org/wiki/Абстрактный_автомат
Всё он отражает.

Там явно по смыслу должна быть «связь», «корреляция».

Словари с тобой не согласны: http://www.thefreedictionary.com/entangle

quantum-troll ★★★★★ ()
Ответ на: комментарий от beastie

regexp — это finite state machine. Как только ты это поймёшь — всё станет сразу ясно.

На практике даже в POSIX Basic есть backreferences, которые конечный автомат обработать не сможет.

proud_anon ★★★★★ ()
Ответ на: комментарий от xlsparse

Может быть Вы говорите про детерминированный автомат?

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

proud_anon ★★★★★ ()
Ответ на: комментарий от xlsparse

Почему он не может его обработать? У него что нет памяти?

У него память ограничена конечным числом состояний, тогда как нумерованные группы могут иметь любую длину. Например, (a+)b\1 — контекстно-свободный язык, который, тем не менее, поддерживается во всех популярных диалектах «регулярных» выражений.

proud_anon ★★★★★ ()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от proud_anon

То есть, вы готите сказать что a+ имеет бесконечную длину? Во первых, эта длина все равно ограничена длиной входной строки, во-вторых, длина этой подстроки не имеет никакого отношения к состоянию автомата.

xlsparse ()
Ответ на: комментарий от xlsparse

Во первых, эта длина все равно ограничена длиной входной строки

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

во-вторых, длина этой подстроки не имеет никакого отношения к состоянию автомата.

Ну и как же будет выглядеть конечный автомат, распознающий (a+)b\1, если количество символов a до b должно быть строго таким же, что и после b?

На этом я этот спор заканчиваю. Во-первых, оффтопик, во-вторых, мне кажется, что ты очередная реинкарнация анонiмуса.

proud_anon ★★★★★ ()
Последнее исправление: proud_anon (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.