РЕДАКТИРОВАТЬ : Я неправильно понял ОП и отправил неверный ответ. Я изменил его на ответ, который, как мне кажется, решил бы проблему в более общем сценарии.
Для файла, подобного приведенному ниже:
$ cat input
abc
123%
123
abc%
this is 456% and nothing more
456
Использование sed -n -E 's/(^|.*[^0-9])([0-9]{1,3})%.*/\2/p' input
$ sed -n -E 's/(^|.*[^0-9])([0-9]{1,3})%.*/\2/p' input
123
456
Флаг -n
делает sed для подавления автоматического вывода строк. Затем мы используем флаг -E
, который позволит нам использовать расширенные регулярные выражения. (В GNU sed флаг не -E
, а вместо -r
).
Теперь идет команда s///
. Группа (^|.*[^0-9])
соответствует либо началу строки (^
), либо серии из нуля или более символов (.*
), заканчивающейся нецифровым символом ([^0-9]
).
[0-9]\{1,3\}
просто соответствует от одной до трех цифр и привязывается к группе (разделителями группы (
и )
), если группе предшествует (^|.*[^0-9])
, за которой следует %
. Тогда .*
соответствует всему до и после этого шаблона. После этого мы заменяем все на вторую группу (([0-9]{1,3})
), используя обратную ссылку \2
. Поскольку мы передали -n
в sed, ничего не печаталось, но мы передали флаг p
команде s///
. В результате , если замена выполняется , то полученная строка печатается. Обратите внимание, что p
- это флаг из s///
, , а не команда p
, потому что она приходит сразу после последней /
.