Как выполнять арифметические операции над значением, возвращаемым uniq -c? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть файл журнала доступа веб-сервера Apache.Используя команды оболочки Linux / UNIX, я посчитал число уникальных дат в файле.Команда uniq -c возвращает количество вхождений каждой уникальной даты в файле.Можно ли выполнять арифметические операции со значением, возвращаемым uniq -c, или есть другие способы подсчета случаев и выполнения арифметических операций?Вот мои комманд Linux:

grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/\2-10-\1/' | sort | uniq -c | sort -ru | head -10

А вот вывод:

358 2006-10-09
348 2006-10-10
347 2006-10-01
344 2006-10-20
339 2006-10-25
337 2006-10-24
337 2006-10-12
336 2006-10-06
336 2006-10-02
335 2006-10-19

1 Ответ

0 голосов
/ 09 октября 2018

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

awk 'BEGIN{ ere="[0-9][0-9]/[A-Z][a-z][a-z]/[0-9][0-9][0-9][0-9]" }
     (match($0,ere)){ date=substr($0,RSTART,RLENGTH); a[date]++; n++ }
     END { for (date in a) {
              yyyy=substr(date,8,4);
              mm=(index("JanFebMarAprMayJunJulAugSepOctNovDec",substr(date,4,3))+2)/3
              mm=sprintf("%0.2d",mm)
              dd=substr(date,1,2)
              print a[date],a[date]/n,yyyy"-"mm"-"dd
           }
     }' log.txt

Поскольку вы упоминаете, что вы хотите делать это только с помощью команд оболочки Linux / Unix, я будувозьмите на себя свободу предположить, что вы имеете в виду .Существует много других типов оболочек, но давайте возьмем самый распространенный.

Ну короче, нет, это невозможно. не поддерживает арифметику с плавающей запятой, но вы можете ее подделать.Пример:

$ echo $(( 2/3 ))
1
$ printf "%f\n" "$(( 10**15 * 2 / 3  ))E-15"
0.666667

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

# total number of dates
n=3417

grep -E [0-9][0-9]/[A-Z]{1}[a-z]{2}/[0-9]{4} log.txt | sed 's/.*\(..\)\/Oct\/\(....\).*/\2-10-\1/' | sort | uniq -c | sort -ru | head -10 | \
while read -r count date; do
   printf "%f %d %s\n"  "$(( 10**15 * count / n  ))E-15" "$count" "$date"
done

Но так как вы уже используете , я бы еще предложил

...