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

Извините за некробампинг этого вопроса, которому уже почти 4 --года, но он занимает довольно высокое место в результатах поиска в Интернете и требует немного большего внимания.

Более точное регулярное выражение (да, я знаю, несмотря на справочную страницу):

^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$

Надеюсь, это поможет некоторым из тех, кто ищет.

Разбить:

  1. Он должен начинаться(^)только со строчной буквы или подчеркивание([a-z_]). Это занимает ровно 1 символ.

  2. Тогда это должно быть одно из либо((... )):

    1. От 0 до 31 символов({0,31})из букв , цифр , подчеркиваний и/ или дефисы ([a-z0-9_-]),

    ИЛИ(|)

    1. От 0 до 30 символов указанного выше плюс знак доллара США(\$)в конце,

    , а затем

  3. Нет больше символов после этого шаблона($).

Те, кто не знаком с регулярными выражениями, могут спросить, почему знак доллара имел обратную косую черту в 2.2, а не в 3. Это потому, что в большинстве (all? )варианты регулярных выражений, знак доллара указывает на конец строки (или строки и т. д. ). В зависимости от используемого движка его нужно будет экранировать, если он является частью фактической строки (Я не могу придумать движок регулярных выражений, который не использует обратную косую черту в качестве экранирования ).

Обратите внимание, что Debian и Ubuntu снимают некоторые ограничения, например, для имени пользователя, полностью совместимого с POSIX/shadow upstream (, и я не знаю, было ли это исправлено, но они позволяют имени пользователя начинаться с цифры – что на самом деле и вызвало эту ошибку). Если вы хотите гарантировать кросс-платформу -,Я бы рекомендовал указанное выше регулярное выражение, а не то, что проходит/не проходит проверку в Debian, Ubuntu и других.

0
27.03.2020, 09:14
7 ответов

Это может быть проще сделать в awk:

awk -F: '/cpu MHz/ {print int($2); exit}' /proc/cpuinfo
  • -F:-разделить на:
  • /cpu MHz/в строках, соответствующих cpu MHz, сделайте :
    • {print int($2); exit}'-преобразовать второе поле в целое число, вывести его и выйти (, чтобы получить только первое совпадение)
4
28.04.2021, 23:20

Есть много возможностей. Вот еще один:

grep -m 1 'cpu MHz' /proc/cpuinfo | cut -f2 -d: | cut -f1 -d.
0
28.04.2021, 23:20

Ниже находится "Попробовать"

команда

sed -n '/cpu MHz/s/.*://p' /proc/cpuinfo | sed "s/\..*//g"

Метод Awk

awk  -F ":" '/cpu MHz/{gsub(/\..*/,"",$NF);print $NF}' /proc/cpuinfo

питон

#!/usr/bin/python
import re
k=re.compile(r'cpu MHz')
m=open('/proc/cpuinfo','r')
for i in m:
    if re.search(k,i):
        print i.split(":")[-1].split(".")[0]
0
28.04.2021, 23:20

Использование sed

grep -m 1 'cpu MHz' /proc/cpuinfo | sed -r 's/^(.*? )([0-9]+)(\..+)$/\2/g'
0
28.04.2021, 23:20

Сgrep:

grep -om1 'cpu MHz[^.]*' /proc/cpuinfo | grep -o '[[:digit:]]*'

Получить строку без точки и следующих символов, затем grepдля цифр.

Если ваш grepподдерживает Perl -совместимые регулярные выражения (PCRE):

grep -oPm1 'cpu MHz.* \K[[:digit:]]+' /proc/cpuinfo

Все до \Kсопоставляется как обычно, но не включается в вывод (просмотра назад переменной длины ).

0
28.04.2021, 23:20

среднее:

awk '/cpu MHz/{SUM+=$NF; LINE+=+1}END {printf "%0d",SUM/LINE}' /proc/cpuinfo

0
28.04.2021, 23:20

Добавление якоря (, например начального пробела ), должно дать вам то, что вам нужно:

$ grep -m 1 '^cpu MHz' /proc/cpuinfo | grep -oE ' [0-9]+'
 900

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

$ grep -m 1 '^cpu MHz' /proc/cpuinfo | grep -oE '[0-9]+\.'
900.

Если проблема возникает и с пробелом, и с точкой, нам нужно перейти к регулярному выражению более высокого уровня, PCRE:

$ grep -oPm 1  '^cpu MHz.* \K[0-9]+(?=\.)' /proc/cpuinfo
900

Который проверяет и пробел, и точку, но не печатает ни того, ни другого.

Эквивалентом sed может быть:

$ sed -nE 's/^cpu MHz.* ([0-9]+)\..*$/\1/p;T;q' /proc/cpuinfo
900

И с awk:

$ awk -F '[.]' '/^cpu MHz/{print $3;exit}' /proc/cpuinfo
900
0
28.04.2021, 23:20

Теги

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