Извлечение числа из постоянного выхода в Bash

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

m  17:24:34|ethminer  Speed 377.61 Mh/s    gpu/0 29.01  gpu/1 29.91  gpu/2 30.21  gpu/3 28.71  gpu/4 28.11  gpu/5 27.96  gpu/6 28.71  gpu/7 29.01  gpu/8 28.48  gpu/9 28.86  gpu/10 29.91  gpu/11 29.08  gpu/12 29.68  [A1484+5:R0+0:F0] Time: 04:19

Я хочу извлечь целое число после «Скорость», которое в этом случае составляет 377. До сих пор я предполагаю, что строка называется string:

$string |  grep -oP '(?<=Speed).*'

я получил

377.61 Mh/s    gpu/0 29.01  gpu/1 29.91  gpu/2 30.21  gpu/3 28.71  gpu/4 28.11  gpu/5 27.96  gpu/6 28.71  gpu/7 29.01  gpu/8 28.48  gpu/9 28.86  gpu/10 29.91

Я хочу избавиться от завершающей строки, выполнив:

$string |  grep -oP '(?<=Speed).*'  | grep -o -E '[1-9][0-9][0-9]*'

но это регулярное выражение неверно, оно ничего не выходит. Как я могу это исправить?

С уважением

Всего 5 ответов


Вы можете использовать

grep -Po 'Speeds*Kd+'

Или, чтобы получить дробную часть, если это необходимо

grep -Po 'Speeds*Kd+(.d+)?'

Смотрите онлайн-демонстрацию

подробности

  • Speed - буквальная подстрока
  • s* - 0+ пробелы
  • K - оператор сброса совпадений (отбрасывание всего текста, сопоставленного до сих пор от значения соответствия)
  • d+ - 1 + цифры
  • (.d+)? - необязательная последовательность . и 1 + цифры

Если вывод всегда такой (т. cut -d' ' -f6 нет лишних строк), простое cut -d' ' -f6 будет выполнять эту работу.


awk 'match($0,"Speed [0-9]+.?[0-9]*"){print substr($0,RSTART+6,RLENGTH-6)}'
sed '/Speed/s/.*Speed ([^ ]*).*/1/'

и если каждая строка всегда одинаково отформатирована, вы можете сделать:

awk '{print $6}' file

Это означает, что каждая строка всегда имеет скорость слова в столбце 5, и вы хотите напечатать столбец 6.


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

awk '{sub(/.*Speed /,"");sub(/ .*/,"")} 1' Input_file

Если вы хотите сохранить вывод в самом файле Input_file, попробуйте сделать следующее.

awk '{sub(/.*Speed /,"");sub(/ .*/,"")} 1' Input_file > temp_file && mv temp_file Input_file

Объяснение: добавление объяснения тоже здесь.

awk '                  ##awk script starts from here.
{
  sub(/.*Speed /,"")   ##Using sub for substitution operation which will substitute from starting of line to till Speed string with NULL fir current line.
  sub(/ .*/,"")        ##Using sub for substitution of everything starting from space to till end in current line with NULL.
}
1                      ##Mentioning 1 will print edited/non-edited lines in Input_file.
' Input_file           ##Mentioning Input_file name here.

sed работает тоже.

$: echo $string | sed -En '/ Speed /{ s/.* Speed ([0-9]+).*/1/; p; }'
377

Есть идеи?

10000