почему grep не возвращает все числа чисел? - PullRequest
0 голосов
/ 24 сентября 2018

Выполнение echo "123456" | grep -Eo "[[:digit:]]{1,2}" вернет пары деревьев, 12, 34, 56.Почему не возвращается 12, 23, 34, 45, 56?

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Хотя у вас уже есть действительный ответ, если ваша оболочка bash (или другая расширенная оболочка, которая допускает строковые индексы), было бы гораздо эффективнее использовать встроенную в bash строковую индексацию ицикл for в стиле C для вывода каждой пары в заданной строке вместо создания отдельной подоболочки на каждой итерации цикла, созданной путем вызова sed.

Индексирование строки Bash позволяет получить доступ к len символамвнутри строки, начинающейся с индекса start (где действительные индексы 0 - len-1), используя форму:

${var:$start:$len}

В сочетании с циклом for в стиле C, циклически повторяющимся по каждому индексу i встрока, начинающаяся с индекса 1 (2-й символ) и выводящая пару символов, созданную с помощью:

"${var:$((i-1)):2}"

Коротким примером будет:

str=123456

for ((i = 1; i < ${#str}; i++)); do 
    echo "${str:$((i-1)):2}"
done

ПримерИспользование / Вывод

$ str=123456; \
for ((i = 1; i < ${#str}; i++)); do echo "${str:$((i-1)):2}"; done
12
23
34
45
56

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 24 сентября 2018

Ваше регулярное выражение не печатает все 5 пар чисел, потому что вы запрашиваете только три.

Ваше регулярное выражение эквивалентно [0-9][0-9] и будет проверять это конкретное совпадение, начиная слева;так что если у вас есть 123456, шаги будут выглядеть примерно так:

  • 1 -> Match?Нет;ничего не печатать.
  • 12 -> Совпадение?Да;распечатайте его.
  • 3 -> Совпадение?Нет;ничего не печатать.

И так далее ...

Обратите внимание, что он не запускается снова после матча, иначе он будет совпадать с 12 снова и снова...

Вы можете использовать другие решения для своей задачи.

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

#!/bin/bash
check_pairs() {
  local str="${1}"
    if [ "${#str}" -ge 2 ]; then
      printf "%s\n" "${str}" | sed -e "s/^\([0-9][0-9]\).*$/\1/"
      check_pairs "${str#?}"
    fi  
}
check_pairs "123456"
exit 0

Возможно, есть другие решения (лучше, быстрее, сильнее), но я не могу думать о них сейчас.

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