Получить первые проценты из списка в bash - PullRequest
3 голосов
/ 07 ноября 2019

Я пытался найти решение весь день. В конце концов я получил доступ к вопросу, который предоставил две команды. Это:

echo blabla 20% a13724bla-bla244 35% | sed -e 's/[^%0-9 ]*//g;s/  */\n/g' | sed -n '/%/p'
echo blabla 20% a13724bla-bla244 35% | sed 's/.*[ \t][ \t]*\([0-9][0-9]*\)%.*/\1/'

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

Когда я пытаюсь использовать вторую команду, я получаю последний процент в моем списке, который мне не нужен. Мне нужен первый процент. Любая помощь с этим будет принята с благодарностью.

Ответы [ 4 ]

3 голосов
/ 07 ноября 2019

perl было бы проще использовать, так как он поддерживает не жадный квантификатор

$ echo 'blabla 20% a13724bla-bla244 35%' | perl -pe 's/.*?(\d+%).*/$1/'
20%
  • .*? минимально соответствует любому символу
  • (\d+%) первое число после% комбинация
  • .* остаток строки
  • $1 заменить строку текстом, совпадающим с ()
2 голосов
/ 07 ноября 2019

Если у вас есть grep, это, вероятно, самый простой вариант для работы:

$ echo blabla 20% a13724bla-bla244 35% |
  grep -o "[0-9]\+ \?%"                   # at least one number, possibly a space and %
20%
35%

, а если вам нужен только первый, передайте предыдущее значение head -1:

$ echo blabla 20% a13724bla-bla244 35% |
  grep -o "[0-9]\+ \?%" |                 # at least one number, possibly a space and %
  head -1                                 # take the first
20%
2 голосов
/ 07 ноября 2019

Проблема с вашим заданным регулярным выражением, .* всегда имеет тенденцию быть жадным, пытаясь сопоставить самую длинную доступную строку. Таким образом, вторая попытка напрямую пытается соответствовать последовательности, которая присутствует в последней.

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

sed 's/^[^0-9%]*\([0-9]*\)%.*/\1/'

Помните, что использовать awk или perl намного проще в подобных случаях. POSIX-ly awk Функции соответствия регулярному выражению могут сделать это, как показано ниже. Функции match() сканируют крайнюю левую подстроку, соответствующую регулярному выражению

awk 'match($0, /([[:digit:]]*)%/){ print substr($0, RSTART, RLENGTH-1) }'
1 голос
/ 07 ноября 2019

Преобразование пробелов в новые строки и grep для строк, заканчивающихся на%:

$ echo 'blabla 20% a13724bla-bla244 35%' | tr ' ' '\n' | grep '%$'
20%
35%
  • Быстрый
  • POSIX
  • Очевидное

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

Если вы беспокоитесь о ложных срабатываниях, настаивайте на вводе чисел, совместимых с вашим форматом. : подписанное, целое, дробное, научное и т. д. Пробелы в червях и т. д.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...