Sed извлекающая группа цифр

Я попытался извлечь номер, как указано ниже, но на экране ничего не печатается:

echo "This is an example: 65 apples" | sed -n  's/.*\([0-9]*\) apples/\1/p'

Однако я получаю "65", если обе цифры сопоставляются отдельно, как указано ниже:

echo "This is an example: 65 apples" | sed -n  's/.*\([0-9][0-9]\) apples/\1/p'
65

Как я могу сопоставить число, чтобы я не знал числа цифр в числе, которое нужно извлечь, например. это может быть 2344 вместо 65?

Ответ 1

$ echo "This is an example: 65 apples" | sed -r  's/^[^0-9]*([0-9]+).*/\1/'
65

Ответ 2

Это потому, что ваш первый .* жадный, а ваш [0-9]* позволяет 0 или более цифр. Следовательно, .* подбирает столько, сколько может (включая цифры), а [0-9]* ничего не соответствует.

Вы можете сделать:

echo "This is an example: 65 apples" | sed -n  's/.*\b\([0-9]\+\) apples/\1/p'

где я заставил [0-9] совместить хотя бы одну цифру, а также добавил границу слова перед цифрами, чтобы все число соответствовало.

Однако проще использовать grep, где вы сопоставляете только число:

echo "This is an example: 65 apples" | grep -P -o '[0-9]+(?= +apples)'

-P означает "perl regex" (так что мне не нужно беспокоиться об экранировании "+" ).

-o означает "печатать только совпадения".

(?= +apples) означает соответствие цифр, за которыми следует слово apples.

Ответ 3

То, что вы видите, - это жадное поведение регулярного выражения. В первом примере .* копирует все цифры. Что-то вроде этого:

echo "This is an example: 65144 apples" | sed -n  's/[^0-9]*\([0-9]\+\) apples/\1/p'
65144

Таким образом, вы не можете сопоставить любые цифры в первом бите. Некоторые диалекты регулярных выражений имеют способ запросить не-жадное сопоставление, но я не верю, что sed имеет один.

Ответ 4

Простой способ для извлечения всех чисел из строки

echo "1213 test 456 test 789" | grep -P -o "\d+"

И результат:

1213
456
789

Ответ 5

echo "This is an example: 65 apples" | ssed -nR -e 's/.*?\b([0-9]*) apples/\1/p'

Для этого вам понадобится супер-сед. -R позволяет perl regexp.