Слияние сумм чисел из разных файлов и удаление выбранных повторяющихся строк - PullRequest
0 голосов
/ 17 декабря 2018

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

Задача

У меня более 10 входных файлов, каждый из которых состоит из двух столбцов чисел (представьте их как x, y точек данных для графика).Цели:

  • Объединить эти файлы в один файл для построения
  • . Для любых повторяющихся значений x в объединении, сложить их соответствующие значения y вместе, а затем напечатать одну строку с x в поле1 и добавленные значения y в поле 2.

Рассмотрим этот пример для 3 файлов:

y1.dat

 25 16

 27 18

y2.dat

 24 10

 27 9

y3.dat

 24 2

 29 3

В соответствии с моими вышеуказанными целями, я должен иметь возможность объединить их в один файл с выводом:

final.dat

 24 12

 25 16

 27 27

 29 3

Попытка

Пока у меня есть следующее:

#!/bin/bash

loops=3

for i in `seq $loops`; do
if [ $i == 1 ]; then
cp -f y$i.dat final.dat

else
awk 'NR==FNR { arr[NR] = $1; p[NR] = $2; next }  {
       for (n in arr) {
       if ($1 == arr[n]) {
       print $1, p[n] + $2
       n++
       }
      }
   print $1, $2 
}' final.dat y$i.dat >> final.dat

fi
done

Вывод:

 25 16
 27 18
 24 10
 27 27
 27 9
 24 12
 24 2
 29 3

При ближайшем рассмотрении ясно, что у меня есть дубликатыисходных значений x.

Проблема в том, что мой сценарий должен сначала распечатать все значения x, а затем я могу добавить их вместе для вывода.Однако я не знаю, как вернуться назад и удалить строки со старыми значениями x, которые мне понадобились для добавления.

Если я слепо использую uniq, я не знаю, старый ли x-values ​​или новое значение x будет удалено.При использовании awk '! Duplicate [$ 1] ++' порядок удаленных строк был изменен в цикле, поэтому он правильно удаляет первый цикл, но не те, которые после этого.

Занимался этим долгоБуду признателен за любую помощь.Спасибо!

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Использование Perl однострочного

> cat y1.dat
25 16
27 18
> cat y2.dat
24 10
27 9
> cat y3.dat
24 2
29 3
> perl -lane ' $kv{$F[0]}+=$F[1]; END { print "$_ $kv{$_}" for(sort keys %kv) }' y*dat
24 12
25 16
27 27
29 3
>
0 голосов
/ 17 декабря 2018

Я предполагаю, что вы уже объединили все файлы в один перед тем, как произвести расчет.Как только это будет сделано, скрипт выглядит так:

awk '{ if ( $1 != "" ) { coord[$1]+=$2 } } END { for ( k in coord ) { print k " " coord[k] } }' input.txt

Надеюсь, это поможет!

Редактировать: Как это работает?

if ( $1 != "" )  { coord[$1]+=$2 } 

Эта строка будет выполнена длякаждая строка в вашем входе.Сначала он проверит, есть ли значение для X, иначе он просто игнорирует строку.Это помогает игнорировать пустые строки, если они есть в вашем файле.Блок, который выполняется: ordin [$ 1] + = $ 2 является сердцем скрипта и создает словарь с X, являющимся ключом каждой записи, и в то же время добавляет каждое значение для найденного Y.

END { for ( k in coord ) { print k " " coord[k] } 

Этот блок будет выполнен после итерации awk по всем строкам в вашем файле.Он просто извлечет каждый ключ из словаря и напечатает его, затем пробел и, наконец, сумму всех найденных значений или, другими словами, значение для этого конкретного ключа.

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