Как с помощью grep и вырезать числа из файла и суммировать их

  1. Файл аутентификации X ( ~ / .Xauthority , / tmp / xauth - * и т. Д.) Содержит имя хоста системы. Если оно отличается от фактического имени хоста (как показано hostname (1) ), приложение X не запустится.

В моем случае выводится сообщение «Протокол не указан Не удалось подключиться к дисплею: ​​0». Но изменение имени хоста в файле аутентификации X на фактическое значение решает проблему. (Я использовал шестнадцатеричный редактор, чтобы проверить это; что ж, должен быть лучший способ изменить это)

3
14.04.2019, 02:02
4 ответа

Вы можете воспользоваться помощью pasteдля сериализации чисел в формате, подходящем для bcдля выполнения сложения:

% grep "30201" logfile.txt | cut -f6 -d "|"
650
1389
945

% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+
650+1389+945

% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984

Если у вас есть grepс PCRE, вы можете сделать это только с grep, используя позитивный просмотр назад:

% grep -Po '\|30201\|.*\|\K\d+' logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984

Только с awk:

% awk -F'|' '$3 == 30201 {sum+=$NF}; END{print sum}' logfile.txt        
2984
  • -F'|'устанавливает разделитель полей как|
  • $3 == 30201 {sum+=$NF}суммирует значения последнего поля, если третье поле30201
  • END{print sum}печатает sumвEND
11
27.01.2020, 21:09

Раствор Баша.

#!/bin/bash
pa=0 ; s=0 ; 
while read a b ; do \
  if [ "$a" == "$pa" ] ; then \
    s=$(($s+$b)) ; 
   else 
    if [ "$pa" != 0 ] ; then \
      echo $pa $s ; 
    fi ; 
    pa=$a ; s=$b ; 
  fi ; 
done < <(cat j.txt | awk -F'|' '{printf("%s %s\n",$3,$6)}' | sort -n) 
echo $pa $s

Инициал. Предыд. А и СУММ

Сократите ввод в поля 3 и 6 и отсортируйте их по номеру

Цикл, пока поле 3 остается прежним, добавить поле 6 в SUM

Если поле 3 изменяется, но Предыдущее A не равно 0, вывести Предыдущее A и СУММ и повторно инициализировать Предыдущее А в а и СУММ в последнее прочитанное поле 6.

Вывод последнего предыдущего A и SUM.

Выход данного входа:

00788 1950
03361 2334
08385 650
08767 650
10234 945
28774 2689
30201 2984
34032 1389
43097 945
0
27.01.2020, 21:09

В ваших командах grep и cut нет ничего плохого. Вы можете сделать его более надежным, используя "|30201|" в качестве шаблона поиска. Тогда проблема заключается в выводе.

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

#!/bin/bash
# get the output as a bash array and add the elements
nums=( $(grep "|30201|" logfile.txt | cut -f6 -d "|") )
total=0

for i in ${!nums[@]}
    do
    total=$(($total+${nums[i]}))
    done
echo $total
1
27.01.2020, 21:09

Один небольшой инструмент, который я держу под рукой, я называю sumcol

#!/bin/sh
# Icarus Sparry. Free for any use.
C=${1:?"missing required column number"}
shift
awk '{s+=$'"$C"'} END { print s }' "$@"

, который суммирует предоставленный вами столбец с разделителями-пробелами. Хотя я бы написал (, как это делает @heemayl)

awk -F'|' '$3 == 30201 {s+=$6} END{ print s}' logfile.txt

для задачи ОП он мог бы использовать

grep "30201" logfile.txt | cut -f6 -d "|" | sumcol 1

или

grep "30201" logfile.txt | tr "| " " _" | sumcol 6
0
27.01.2020, 21:09

Теги

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