Подсчитать количество вхождений шаблона в одной строке

Один из способов - использовать xcape .

xcape [-d] [-t timeout] [-e map-expression]

Это должно помочь:

xcape -e 'Shift_L=parenleft;Shift_R=parenright'

xcape включен как пакет для некоторых дистрибутивов.

Примечания:

Задержка по умолчанию составляет 500 мсек, после чего назначенный ключ не срабатывает. Его можно установить с помощью параметра -t .

Каждое выражение-карта запускается как демон и имеет собственный PID.

0
23.07.2019, 12:41
3 ответа

Сawk:

awk 'BEGIN{print gsub(ARGV[2], "&", ARGV[1])}' abcsdabcsdabc abc

Обратите внимание, что шаблон (здесьabc)принимается awkкак расширенное регулярное выражение (, как будто используется grep -E/egrep).

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

Использовать perlрегулярные выражения (, подобные GNU grep -P's):

perl -le 'print scalar (() = $ARGV[0] =~ m{$ARGV[1]}g)' -- abcsdabcsdabc abc

(обратите внимание, однако, что аргументы не интерпретируются как текст в соответствии с кодировкой локали. Например, в локали UTF -8 с éи .в качестве аргументов он будет сообщать 2 (байта )вместо 1 (символа )).

С помощью zshвы можете сделать:

occurrences() {
  set -o localoptions -o extendedglob

  local n=0
  : ${1//(#m)$2/$((++n))}
  echo $n
}

occurrences abcsdabcsdabc abc

Здесь второй аргумент(abc)интерпретируется как фиксированная строка; замените $2на $~2, чтобы он интерпретировался как расширенный шаблон zsh glob вместо (с более широким набором функций, чем расширенные регулярные выражения, но с другим синтаксисом ).

4
28.01.2020, 02:14

Обработка строки как состоящей из полей, разделенныхabc:

$ echo abcsdabcsdabc | awk -F 'abc' '{ print (length > 0 ? NF - 1 : 0) }'
3

Количество вхождений разделителя abcравно 1 минус количество полей, которые он ограничивает.

$ echo abcsdabcsdabc | awk '{ n=0; while (sub("abc", "xxx")) n++; print n }'
3

Это заменяет подстроку abcиз строки на xxxи подсчитывает, сколько раз это делается, а затем выводит это число. n=0не нужен, если есть только одна строка ввода.

Функция gsub()в awkвозвращает количество сделанных замен, поэтому приведенное выше можно упростить до

$ echo abcsdabcsdabc | awk '{ print gsub("abc", "xxx") }'
3

В bashможно сделать то же самое, что и в той awkпрограмме, которая используетsub():

string=abcsdabcsdabc

n=0
while [[ $string == *abc* ]]; do
    n=$(( n+1 ))
    string=${string/abc/xxx}  # replace first occurrence of "abc" with "xxx"
done
printf '%d\n' "$n"

При этом используется цикл whileдля замены подстроки abcиз значения в $stringна xxxдо тех пор, пока в $stringне будет найдено больше вхождений abc, точно так же, как второй awkпрограмма выше делает.

3
28.01.2020, 02:14

с использованием Raku (ранее известного как Perl _6)

~$ echo "abcsdabcsdabc" | raku -ne '.match("abc", :global).say;'
(「abc」 「abc」 「abc」)

Выше приведены совпадения (строки -с -строкой ). Ниже указано количество совпадений (строка -по -строка):

~$ echo "abcsdabcsdabc" | raku -ne '.match("abc", :global).elems.say;'
3

Обратите внимание :аргумент :globalможно сократить до :g.

ХТН.

https://raku.org/

0
12.09.2020, 21:23

Теги

Похожие вопросы