perl -n -E 'say $1 while m!/id(\d{9})!g' input-file
должно работать. Это предполагает ровно 9 цифр; это {9}
в приведенном выше. Вы можете выбрать 8 или 9 ({8,9}
), 8 или более ({8,}
), до 9 ({0,9}
) и т. Д.
Пример этой работы:
$ echo -n 'junk jumk http://foo/id231313 junk lalala http://bar/id23123 asda' | perl -n -E 'say $1 while m!id(\d{0,9})!g'
231313
23123
Конечно, это вариант с 0 по 9.
Если вы застряли с perl до 5.10, используйте -e
вместо -E
и print "$1\n"
вместо say $1
.
Как это работает
Первый - это два аргумента командной строки для Perl. -n
говорит Perl читать строку из стандартного ввода или файлов, заданных в командной строке, построчно, устанавливая $_
для каждой строки. $_
является целью Perl по умолчанию для многих вещей, включая совпадения с регулярными выражениями. -E
просто сообщает Perl, что следующим аргументом является однострочный Perl, использующий новые возможности языка (по сравнению с -e
, который не использует расширения 5.10).
Итак, глядя на одну строку: say
означает распечатать какое-то значение, за которым следует новая строка. $1
- первый захват регулярного выражения (захват производится в круглых скобках в регулярных выражениях). while
- это циклическая конструкция, с которой вы, вероятно, знакомы. m
является оператором совпадения, !
после него является разделителем регулярного выражения (обычно вы видите /
здесь, но поскольку шаблон содержит /
, проще использовать что-то другое, поэтому чтобы избежать /
как \/
). /id(\d{9})
- регулярное выражение для сопоставления. Имейте в виду, что разделитель !
, поэтому /
не является особенным, он просто соответствует буквальному /
. Скобки образуют группу захвата, поэтому $1
будет числом. !
- это разделитель, за которым следует g
, что означает совпадение столько раз, сколько возможно (в отличие от одного). Это то, что заставляет его подбирать все URL в строке, а не только первый. Пока есть совпадение, оператор m
будет возвращать истинное значение, поэтому цикл будет продолжаться (и запускать этот say $1
, распечатывая совпадение).
Раствор с двумя седлами
Я думаю это один из способов сделать это только с помощью sed. Гораздо сложнее!
echo 'junk jumk http://foo/id231313 junk lalala http://bar/id23123 asda' | \
sed 's!http://!\nhttp://!g' | \
sed 's!^.*/id\([0-9]*\).*$!\1!'