Ответ 1
$ echo "This is an example: 65 apples" | sed -r 's/^[^0-9]*([0-9]+).*/\1/'
65
Я попытался извлечь номер, как указано ниже, но на экране ничего не печатается:
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?
$ echo "This is an example: 65 apples" | sed -r 's/^[^0-9]*([0-9]+).*/\1/'
65
Это потому, что ваш первый .*
жадный, а ваш [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.
То, что вы видите, - это жадное поведение регулярного выражения. В первом примере .*
копирует все цифры. Что-то вроде этого:
echo "This is an example: 65144 apples" | sed -n 's/[^0-9]*\([0-9]\+\) apples/\1/p'
65144
Таким образом, вы не можете сопоставить любые цифры в первом бите. Некоторые диалекты регулярных выражений имеют способ запросить не-жадное сопоставление, но я не верю, что sed
имеет один.
Простой способ для извлечения всех чисел из строки
echo "1213 test 456 test 789" | grep -P -o "\d+"
И результат:
1213
456
789
echo "This is an example: 65 apples" | ssed -nR -e 's/.*?\b([0-9]*) apples/\1/p'
Для этого вам понадобится супер-сед. -R позволяет perl regexp.