Скрипт для суммирования столбцов в нескольких файлах - PullRequest
0 голосов
/ 12 февраля 2019
File A
Sector A    100
Sector B    200
Sector C    300
Sector D    500


File B
Sector A    100
Sector B    200
Sector C    300
Sector D    500


File C
Sector A    100
Sector B    200
Sector C    300
Sector D    500

Я хотел бы получить один файл с суммой секторов A, B, C всех файлов.

Окончательный результат

Sector A    300
Sector B    600
Sector C    900
Sector D    1500

Было бы здорово создать сценарий оболочки!!!Ваше предложение приветствуется.

Ответы [ 5 ]

0 голосов
/ 12 февраля 2019

Используя Perl,

$ perl -0777 -ne ' s/^(.+) (\d+)$/$kv{$1}+=$2/gme; END { for(sort keys %kv) { print "$_ $kv{$_}\n" }} ' filea.txt fileb.txt  filec.txt
Sector A    300
Sector B    600
Sector C    900
Sector D    1500
$
0 голосов
/ 12 февраля 2019

1 . sort ассистируется awk

$  sort filea.txt fileb.txt  filec.txt | awk ' { c=$2; if(c!=p && NR>1 ) { print $1,p,s;s=0} p=c;s+=$3 } END { print $1,p,s } '
Sector A 300
Sector B 600
Sector C 900
Sector D 1500
$

2. paste ассистируется awk

$ paste filea.txt fileb.txt  filec.txt | awk ' { for(i=3;i<=NF;i+=3) s+=$i; print $1,$2,s ; s=0 } '
Sector A 300
Sector B 600
Sector C 900
Sector D 1500
$
0 голосов
/ 12 февраля 2019

Предполагая, что ваши столбцы разделены вкладками, вы можете использовать GNU datamash:

sort fileA fileB fileC | datamash groupby 1 sum 2

Вывод

Sector A    300
Sector B    600
Sector C    900
Sector D    1500

Если ваши (возможно большие) отдельные входные файлы уже отсортированы, вы можете ускоритьПроцесс sort -m ... вместо sort.

0 голосов
/ 12 февраля 2019

Не самое умное решение, но довольно простое и понятное:

for f in fileA fileB fileC
do
   while read line
   do
   A=$(echo $line | grep "Sector A" | tr -s " "| cut -d' ' -f3)
   B=$(echo $line | grep "Sector B" | tr -s " "| cut -d' ' -f3)
   C=$(echo $line | grep "Sector C" | tr -s " "| cut -d' ' -f3)
   D=$(echo $line | grep "Sector D" | tr -s " "| cut -d' ' -f3)
   secA=$((secA+A))
   secB=$((secB+B))
   secC=$((secC+C))
   secD=$((secD+D))
   done < $f
done
echo "Sector A" $secA
echo "Sector B" $secB
echo "Sector C" $secC
echo "Sector D" $secD
0 голосов
/ 12 февраля 2019

Не могли бы вы попробовать следующее.

awk '{a[$1 FS $2]+=$NF} END{for(i in a){print i,a[i]}}' fileA fileB fileC

Вывод будет следующим.

Sector A 300
Sector B 600
Sector C 900
Sector D 1500
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...