Grep остаток строки ... после матча

8

У меня есть файл, содержащий только две строки, со следующей структурой:

$ cat /tmp/pwpower.log
000D6F0000D34227, -114.10
000D6F0001A405C4, -130.09

Значения являются значениями мощности моей солнечной электростанции. Отрицательное значение означает поколение.

Мне нужно, чтобы значения извлекались через grep / sed / awk - какой бы самый умный способ. Мне нужно извлечь оба значения отдельно и без знака минус.

То, что я делаю сейчас, отчасти глупо, но это работает - я уверен, что многие из вас найдут для меня более разумные способы :-) Здесь, конечно, я вижу только значения плюс минус.

Чтобы получить первое значение:

cat /tmp/pwpower.log |grep -o "\-.*" | head -n 1

Чтобы получить второе значение:

cat /tmp/pwpower.log |grep -o "\-.*" | tail -n1

И связанный с этим вопрос, есть ли простой способ взять эти STRING и преобразовать их, чтобы я мог вычислить SUM?

njordan
источник

Ответы:

12

Все значения:

$ awk -F '[ -]*' '$0=$NF' /tmp/pwpower.log
114.10
130.09

Значение в первой строке:

$ awk -F '[ -]*' 'NR==1{print $NF;exit}' /tmp/pwpower.log
114.10

Значение во второй строке:

$ awk -F '[ -]*' 'NR==2{print $NF;exit}' /tmp/pwpower.log
130.09

Сумма всех значений:

$ awk -F '[ -]*' '{sum+=$NF} END{print sum}' /tmp/pwpower.log
244.19
Адриан Фрювирт
источник
1
Ваш FS не должен быть таким сложным: -F-будет делать.
Гленн Джекман
Для более сложного ввода, если вы не знаете, есть ли в предыдущих полях пробелы, вы можете использовать запятую в качестве разделителя полей и пропустить все tr -d "- "сначала.
Джейсон С
@glennjackman То, как я интерпретирую вопрос, состоит в том, что значение может быть неотрицательным (без генерации), которое порождает просто -F-.
Адриан Фрувирт
На самом деле, я не читал это внимательно.
Гленн Джекман
8

Вы можете использовать, cutчтобы выбрать 2-й столбец чисел и paste -sd+создать серию чисел для сложения. Затем инструмент bcможно использовать для расчета.

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Как это работает

Выбирает числа из 2-го столбца.

$ cut -d',' -f2 pwpower.log 
 -114.10
 -130.09

Переформатируйте их в одну строку со +знаком между каждым числом:

$ cut -d',' -f2 pwpower.log | paste -sd+
 -114.10+ -130.09

Выполняет расчет:

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Чтобы получить абсолютное значение:

$ cut -d',' -f2 pwpower.log | sed 's/-//g' | paste -sd+ | bc
244.19

Если формат файла pwpower.logгарантирован, вы можете cutопустить знак минус:

$ cut -d'-' -f2 pwpower.log | paste -sd+ | bc
244.19
SLM
источник
6

Поцелуй подход

$ awk '{print -$2; t+=-$2}; END{print t}' pwpower.log 
114.1
130.09
244.19
steeldriver
источник
1
ПОЦЕЛУЙ? Что это?
Бернхард
Сохраняя это простым и глупым;)
Steeldriver
@ да, но, если я не прочитал, ОП специально попросил удалить знак
steeldriver
@steeldriver - ах да, мой плохой, я пропустил это предложение, похороненное там.
SLM
4
Держать его просто глупо. Подразумевать, когда вы не делаете это простым, вы глупы.
Мэтт
4

Мне нравится ваша команда grep, но ее можно улучшить, удалив знак минус, и работать в тех случаях, когда знак минус отсутствует. Расширенные регулярные выражения, доступные в GNU grep с -Eфлагом, позволяют нам более точно соответствовать числу.

Несколько эффективнее не использовать cat, но передать имя файла в качестве аргумента первой команде и позволить ей прочитать файл. Мне также приходит в голову, что если вы имеете дело только с первыми или последними строками файла, имеет смысл сначала использовать команды headили, tailчтобы вам соответствовало только одна строка grep.

Первое значение:

$ head -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$' 
114.10

Последнее значение:

$ tail -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$'
130.09

Сумма (с помощью команды awk отсюда ):

$ grep -oE '[0-9\.]+$' /tmp/pwpower.log | awk '{s+=$1} END {print s}'
244.19
Стивен Остермиллер
источник
3
[root@ip-10-186-149-181 ~]# cut -d '-' -f2 /tmp/pwpower.log | paste -sd+ | bc
244.19

Это сделает расчет без минуса.

Я думаю, что сократить быстрее, чем awk, в общем

CSNY
источник
1

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

$ awk -F, '{ print -$2 }' < /tmp/pwpower.log
114.1
130.09

Если будут какие-то положительные числа, они получатся отрицательными. Если вы хотите только сумму, awkможете сделать это тоже:

$ awk -F, '{ sum += -$2 } END { print sum }' < /tmp/pwpower.log
244.19
zwol
источник
В awk вы можете использовать sqrt($2^2)как трюк, чтобы получить абсолютное значение.
Джейсон С
@JasonC Это умно, но в контексте я считаю, что это было бы неправильно.
zwol
0

Для суммирования двух значений:

(awk -F- '{printf "%s+", $2}' /tmp/pwpower.log; echo 0) | bc -l
хаос
источник
Это все немного избыточно. Почему на земле Nog использовать параметры расчета awk?
Бернхард
1
да, правда, но мне нравится bc=)
хаос
1
Ой, хорошо, тогда зачем использовать awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Бернхард
@ Бернхард Ну зачем использовать cut? Используйте [insert_cmd_here]вместо этого, создайте петлю подоболочки, придумайте новую математику, используйте человеческий кластер или умственную арифметику, направьте мои мысли в bc. Почему мы делаем вещи? Нет причин делать мой ответ плохим.
хаос
0

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

$-sed -r 's/[^-]+.(.*)/\1/g' /tmp/pwpower.log
Каланидхи М.
источник