Как подсчитать количество вхождений набора символов? - PullRequest
0 голосов
/ 27 сентября 2018

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

Набор символов, который я хочу подсчитать, следующий:

!"#$%&'()*+

Я пробовал следующее:

{
    s = $0;
    print(gsub(/!\"#\$%&\'()\*\+/, "",  s);
}

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

Один простой пример:

# prints 1
AAAEEEA#AA

# prints 0
AAAEEEAAAA

# prints 4
AA((EE!!AA

Ответы [ 3 ]

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

одинарная кавычка требует особой обработки, вы можете сделать цепочку кавычек, как показано ниже

$ awk '{print gsub(/[!"#$%&'"'"'\(\)*+]/,"")}' 

, также вам не нужно указывать третий аргумент, по умолчанию это $0.

0 голосов
/ 27 сентября 2018
$ awk '{print $0, gsub(/[!"#$%&\047()*+]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

Приведенный выше список символов, которые вас интересуют, представляет собой список символов в выражении в скобках , поэтому они обрабатываются как набор букв, для использования \047представляет ', поэтому он будет работать в командной строке или в файле и использует & в качестве замены gsub(), поэтому он фактически не изменит вашу запись без необходимости использования временной переменной.

В качестве альтернативы может существовать класс символов , такой как [:punct:], который может использоваться внутри выражения скобки в качестве альтернативы явному списку символов , который соответствует вашим потребностямНапример:

$ awk '{print $0, gsub(/[[:punct:]]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

$ awk '{print $0, gsub(/[^[:alnum:]]/,"&")}' file
AAAEEEA#AA 1
AAAEEEAAAA 0
AA((EE!!AA 4

Я выделил правильную терминологию POSIX жирным шрифтом выше.Единственная другая связанная терминология, о которой следует знать, - это то, что вы можете альтернативно указать диапазон символов , например a-z внутри скобочного выражения , например, [a-z].

См. спецификацию POSIX для получения дополнительной информации о выражениях в скобках и классе символов / списках / диапазонах.

Что касается того, почему мы используем восьмеричное вместо hex для представления одинарной кавычки в awk, см. http://awk.freeshell.org/PrintASingleQuote.


Приложение Существуют также другие термины для сопоставления регулярных выражений для наборов символов, которые отличаются от терминологии, определенной стандартом POSIX.До сих пор я нашел следующие ссылки для каждого:

Стандарт POSIX RE:

Определения не-POSIX RE:

Из этих и из опыта за последние 30 лет использования RE и наблюдения, как люди обращаются к различным частям RE, я создал таблицу, чтобы показатьразличия в терминологии:

  Char Set  |       POSIX Terminology       | Non-POSIX Terminology
------------|-------------------------------|---------------------------
    abc     | Character List                | no specific term
------------|-------------------------------|---------------------------
    a-c     | Character Range               | no specific term
------------|-------------------------------|---------------------------
 [:alpha:]  | Character Class               | POSIX Character Class
------------|-------------------------------|---------------------------
   [...]    | Bracket Expression            | Character List or
            |                               | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
   [abc]    | Bracket Expression containing | Character List or
            | a Character List              | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
   [a-c]    | Bracket Expression containing | Character List or
            | a Character Range             | Character Class or
            |                               | Character Set
------------|-------------------------------|---------------------------
[[:alpha:]] | Bracket Expression containing | Character List or
            | a Character Class             | Character Class or
            |                               | Character Set or
            |                               | Bracket Expression

Только в perl . также называется символьным классом (см. https://perldoc.perl.org/perlrecharclass.html) и несколько инструментов и вариантов инструментов (например, GNU-версии стандартных инструментов UNIX).) иметь сокращение для классов символов POSIX, таких как \s для [:space:], и иметь другие escape-последовательности, которые можно использовать так же, как и классы символов - для этого обратитесь к справочной странице по инструментам.

Лучше всего я могусказать, что терминология POSIX ясна, проста и недвусмысленна, тогда как другой терминogy двусмысленна и запутана, поэтому ИМХО лучше придерживаться терминологии POSIX.

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

Решением, как указано в комментарии revo , было использование списка символов:

{
    s = $0;
    print(gsub(/[!"#$%&'()*+]/, "",  s));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...