нормализация столбца в awk - PullRequest
0 голосов
/ 17 ноября 2018

Я совершенно новичок в awk.

Я пытаюсь написать скрипт, который принимает входной файл, находит сумму в третьем столбце, а затем печатает столбцы 1, 2, а затем нормализованныйтретий столбец.Однако, когда я делаю это, я, кажется, делаю это только для последней строки моего входного файла.Я думаю, что мне чего-то не хватает в том, как работает «END».Любые советы?

Спасибо!

BEGIN {
     col= ARGV[2]
     ARGV[2] = ""
}

{s1 += $3}

END {  if (NR > 0){
                print s1;
                print $1, $2, $3/s1
            }
}

ВХОД:

     0          2   8.98002e-05
     1          0   5.66203e-05
     2          2   2.20586e-05
     3          2   5.31672e-05
     4          2   2.17192e-07
     5         26   3.67908e-06
     6          1   1.0385e-05
     7          1   7.78022e-05
     8          0   5.47272e-05
     9          1   6.34726e-05
    10          1   0.000105879
    11          1   4.77847e-05
    12          0   3.05258e-05
    13          0   5.53268e-05
    14          1   7.8916e-05
    15          1   3.02601e-05
    16          1   3.81807e-05

s1: 0.000818803

OUTPUT:
0.000818803
0 2 0.109673
0.000818803
1 0 0.0691501
0.000818803
2 2 0.0269401
0.000818803
3 2 0.0649328
0.000818803
4 2 0.000265256
0.000818803
5 26 0.00449324
0.000818803
6 1 0.0126831
0.000818803
7 1 0.0950194
0.000818803
8 0 0.0668381
0.000818803
9 1 0.0775188
0.000818803
10 1 0.129309
0.000818803
11 1 0.0583592
0.000818803
12 0 0.037281
0.000818803
13 0 0.0675703
0.000818803
14 1 0.0963797
0.000818803
15 1 0.0369565
0.000818803
16 1 0.0466299

1 Ответ

0 голосов
/ 17 ноября 2018

Для этого, так или иначе, вам придется сделать два прохода по записям.Один из способов - прочитать сам файл дважды, как в первом методе, показанном ниже.

При первом проходе сумма столбца 3 просто накапливается в s1.Второй проход печатает первые два столбца с нормализованным третьим.

Обратите внимание, что вам нужно дважды предоставить файл в командной строке, чтобы awk обработал его дважды!

$ awk 'NR == FNR {s1 += $3; next} {print $1, $2, $3/s1}' file file
0 2 0.109673
1 0 0.0691501
2 2 0.0269401
3 2 0.0649329
4 2 0.000265256
5 26 0.00449324
6 1 0.0126832
7 1 0.0950195
8 0 0.0668381
9 1 0.0775188
10 1 0.12931
11 1 0.0583592
12 0 0.037281
13 0 0.0675704
14 1 0.0963798
15 1 0.0369565
16 1 0.0466299

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

Затем в блоке END, которыйзапустить после того, как все записи прочитаны и сумма полностью накоплена, вы перебираете массив, чтобы распечатать результаты.

 awk '    { s1 += $3; a[NR] = $1 OFS $2; b[NR] = $3 }
      END { for (i=1; i<=NR; ++i) print a[i], b[i] / s1 }' file

Этот второй метод имеет очевидные недостатки использования гораздо большего объема памяти - фактическис очень большим файлом этот подход может оказаться невозможным.

Если вы еще не знакомы с конструкцией NR == FNR, см. Что такое "NR == FNR" в awk? ,Также см. Раздел «Обработка двух файлов» в https://backreference.org/2010/02/10/idiomatic-awk/.

...