вычитание определенных полей из строк в файлах csv

#bash #csv #awk

#bash #csv #awk

Вопрос:

У меня есть этот файл :

 Month,CPU,RAM
July 2018,19%,46%
August 2018,20%,45%
September 2018,20%,41%
October 2018,21%,39%
November 2018,21%,39%
December 2018,21%,41%
January 2019,25%,46%
February 2019,27%,50%
  

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

Например :

 July  -> August
CPU :  1% ( because 20-19)

August -> September 
CPU :  0% ( because 20-20)

September -> October
CPU :  1% ( because 21-20)
  

Я пробую это с июля и августа :

 cat myfile.txt | egrep "July|August" | awk -F',' '{diff-=$2} END {print diff}'

  

Но результат :

 39
  

И проблема в том, что я должен указать июль и август, что неэффективно, потому что я должен делать это и для других месяцев.

Есть ли способ вычислить разницу между этими значениями? Мне просто нужно знать разницу между значениями (значение 2 — значение 1, значение 3 — значение 2 — значение 2 — значение 4 — значение 3 и т. Д.), Не обязательно иметь такое же представление, как в моем примере.

Пожалуйста, вы можете мне показать?

Спасибо!

Ответ №1:

 $ awk -F'[ ,%]' '
  NR>3{print ""}
  NR>2{printf "%s -> %snCPU : % d%% (because %d-%d)n",month,$1,$3-usage,$3,usage}
  NR>1{month=$1;usage=$3}
' file
July -> August
CPU :  1% (because 20-19)

August -> September
CPU :  0% (because 20-20)

September -> October
CPU :  1% (because 21-20)

October -> November
CPU :  0% (because 21-21)

November -> December
CPU :  0% (because 21-21)

December -> January
CPU :  4% (because 25-21)

January -> February
CPU :  2% (because 27-25)
  

настроить формат вывода действительно легко даже для новичков. например, если вы хотите получить более компактный вывод:

 $ awk -F'[ ,%]' 'NR>2{printf "%-9s -> %-9s : % 3d%%n",month,$1,$3-usage} NR>1{month=$1;usage=$3}' file
July      -> August    :   1%
August    -> September :   0%
September -> October   :   1%
October   -> November  :   0%
November  -> December  :   0%
December  -> January   :   4%
January   -> February  :   2%
  

Комментарии:

1. Это работает хорошо! Спасибо! Можете ли вы быстро объяснить 4 строки вашего скрипта?

2. @Makmy вам не нужно объяснять это, прочитайте руководство по awk, и вы получите его максимум за 10 минут

Ответ №2:

 $ awk -F'[ ,]' '
    NR>2{ printf "%s -> %snCPU : % d%% ( because %d-%d)nn", p[1], $1, $3-p[3], $3, p[3] }
    { split($0,p) }
' file
July -> August
CPU :  1% ( because 20-19)

August -> September
CPU :  0% ( because 20-20)

September -> October
CPU :  1% ( because 21-20)

October -> November
CPU :  0% ( because 21-21)

November -> December
CPU :  0% ( because 21-21)

December -> January
CPU :  4% ( because 25-21)

January -> February
CPU :  2% ( because 27-25)
  

Комментарии:

1. это выводит дополнительную пустую строку в конце, верно? Я имею в виду, что вы сделали это не случайно

2. @oguzismail Справа — он выводит пустую строку после каждой многострочной выходной записи, как если бы вы выполняли многострочные операции с записью в режиме абзаца RS=""; ORS="nn" . .

Ответ №3:

Другой awk :

 awk -F'[ ,%]' '
               FNR>2{print m " -> " $1;printf "CPU : % d%%%s",$3-u,ORS}
               {m=$1;u=$3}
              ' file
  

Вывод

 July -> August
CPU :  1%
August -> September
CPU :  0%
September -> October
CPU :  1%
October -> November
CPU :  0%
November -> December
CPU :  0%
December -> January
CPU :  4%
January -> February
CPU :  2%
  

Комментарии:

1. Спасибо! А если я хочу удалить первую строку с » Месяц, процессор, оперативная память» и начать с июля? Как это сделать?

2. @Makmy Извините, я вас не понял. Этот скрипт автоматически игнорирует первую строку, поскольку она не имеет отношения к нашим вычислениям.