суммировать значение 3-й строки и соответственно разделить строки - PullRequest
2 голосов
/ 17 июня 2020

У меня есть файл, как показано ниже, с количеством строк n, я хочу суммировать его сумму (на основе 3-го столбца) и соответственно распределить строки в 3 разных файлах (на основе суммы каждого)

Например - если мы просуммируем все значения 3-го столбца, общее количество будет равно 516, а если мы разделим его на 3, это будет 172.

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

Входной файл

a aa 10
b ab 15
c ac 17
a dy 30
y ae 12
a dl 34
a fk 45
l ah 56
o aj 76 
l ai 12 
q al 09
d pl 34
e ik 30
f ll 10
g dl 15 
h fr 17
i dd 23
j we 27
k rt 12
l yt 13
m tt 19

ожидаемый результат

file1(total -163)


a   aa  10
b   ab  15
c   ac  17
a   dy  30
y   ae  12
a   dl  34
a   fk  45

файл2 (всего-153 )

l   ah  56
o   aj  76
l   ai  12
q   al  9

файл3 (всего - 200)

d   pl  34
e   ik  30
f   ll  10
g   dl  15
h   fr  17
i   dd  23
j   we  27
k   rt  12
l   yt  13
m   tt  19

Ответы [ 2 ]

4 голосов
/ 17 июня 2020

Не могли бы вы попробовать следующие, написанные и протестированные с показанными образцами в GNU awk.

awk '
FNR==NR{
  sum+=$NF
  next
}
FNR==1{
  count=sum/3
}
{
  curr_sum+=$NF
}
(curr_sum>=count || FNR==1) && fileCnt<=2{
  close(out_file)
  out_file="file" ++fileCnt
  curr_sum=$NF
}
{
  print > (out_file)
}'   Input_file  Input_file

Пояснение: Добавление подробного объяснения вышеизложенного.

awk '                                               ##Starting awk program from here.
FNR==NR{                                            ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
  sum+=$NF                                          ##Taking sum of last field of all lines here and keep adding them to get cumulative sum of whole Input_file.
  next                                              ##next will skip all further statements from here.
}
FNR==1{                                             ##Checking condition if its first line for 2nd time reading of Input_file.
  count=sum/3                                       ##Creating count with value of sum/3 here.
}
{
  curr_sum+=$NF                                     ##Keep adding lst field sum in curr_sum here.
}
(curr_sum>=count || FNR==1) && fileCnt<=2{          ##Checking if current sum is <= count OR its first line(in 2nd time reading) AND output file count is <=2 here.
  close(out_file)                                   ##Closing output file here, may NOT be needed here since we are having only 3 files here in output.
  out_file="file" ++fileCnt                         ##Creating output file name here.
  curr_sum=$NF                                      ##Keep adding lst field sum in curr_sum here.
}
{
  print > (out_file)                                ##Printing current line into output file here.
}'   Input_file  Input_file                         ##Mentioning Input_file names here.
0 голосов
/ 17 июня 2020
awk '{ L[nr++]=$0; sum+=$3 }
     END{ sumpf=sum/3; sum=0; file=1; 
          for(i in L) { split(L[i],a); 
          if ((sum+a[3])>sumpf && file<3) { file+=1; sum=0; }; 
          print i, L[i] > "file" file;
          sum+=a[3]; 
        }
    }'  input
  • Этот скрипт прочитает все входные данные в массив L и вычислит sum
  • Int в блоке END, вычисляется sumPerFile sumpf, и результат готов.

В отличие от другого решения, здесь требуется только один входной файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...