Баш регулярное выражение. Персонаж не совпадает

Поскольку в последнем случае есть две строки, одна отображается, а другая нет, потому что она отображается в подоболочке с завершающей подсчет новой строкой. Я проверил zsh и bash , такое поведение существует в zsh , bash ведет себя аналогично с другим форматированием.

Взгляните на следующий дамп ASCII из zsh :

/tmp/test% jobs
[1]  + running    tail -f /var/log/syslog

/tmp/test% jobs | wc -l
1

/tmp/test% jobs | od -c
0000000   [   1   ]           +       r   u   n   n   i   n   g        
0000020           t   a   i   l       -   f       /   v   a   r   /   l
0000040   o   g   /   s   y   s   l   o   g  \n
0000052

/tmp/test% cd ..

/tmp% jobs | wc -l
2

/tmp% jobs | od -c
0000000   [   1   ]           +       r   u   n   n   i   n   g        
0000020           t   a   i   l       -   f       /   v   a   r   /   l
0000040   o   g   /   s   y   s   l   o   g  \n   (   p   w   d       n
0000060   o   w   :       /   t   m   p   )  \n
0000072

Кажется, оболочка отслеживает текущий рабочий каталог, посмотрите (pwdn 0000060 ow: / tmp) , круглые скобки обозначают подоболочку.

Вот соответствующий исходный код zsh , jobs.c :

/* print "(pwd now: foo)" messages: with (lng & 4) we are printing
 * the directory where the job is running, otherwise the current directory
 */

    if ((lng & 4) || (interact && job == thisjob &&
                      jn->pwd && strcmp(jn->pwd, pwd))) {
        doneprint = 1;
        fprintf(fout, "(pwd %s: ", (lng & 4) ? "" : "now");
        fprintdir(((lng & 4) && jn->pwd) ? jn->pwd : pwd, fout);
        fprintf(fout, ")\n");
        fflush(fout);
    }

В то время как bash имеет:

      if (strcmp (temp, jobs[job_index]->wd) != 0)
        fprintf (stream,
          _("  (wd: %s)"), polite_directory_format (jobs[job_index]->wd));

Чтобы получить то, что вы хотите, вы может выполнять задания в подоболочке:

( jobs ) | wc -l
0
21.11.2018, 17:05
1 ответ

Скобки были не на том месте.

В ошибочном регулярном выражении вы сгруппировали возможности октета вместе с чередованиями:

^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.)

... что соответствует началу строки ^, за которой следует:

  • 25[0-5]или
  • 2[0-4][0-9]или
  • [01]?[0-9][0-9]?\.

Обратите внимание, что точка является частью третьего возможного чередования. Это заставляет регулярное выражение соответствовать начальному 255, оставляя последующий период несопоставленным.

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

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2}

или вот так:

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

... так что имеется четыре октета.

Это заставляет IP-адрес появляться в строке сам по себе. Если вам все равно, где в строке отображается IP-адрес, отбросьте начальный(^)и конечный($)якоря.

В Linux для наглядности при тестировании можно использовать grep --color=always -E..., например:

$ ip=jeff-255.255.255.255-foo
$ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
jeff-255.255.255.255-foo

... где 255.255.255.255отображается в цвете.

3
28.01.2020, 02:23

Теги

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