0

I have a file that has numeric values in the form of a matrix. I have written an awk script that prints the header, then adds 1 to the columns 'sum' if the values in the columns are less than 5 and greater than 0. Then, at the end, it prints the sum of each column. This part works fine:

awk '
  BEGIN {FS=OFS=" "}
  NR==1 {print}
  NR>1  {for (i=1;i<=NF;i++) if ($i < 5 && $i > 0) a[i]+=1}
  END   {for (i=1;i<=NF;i++) printf $a[i]
}' snp_fake2.txt > tmp.txt`

My goal is to print the entire column if that columns sum is greater than some value THRESHOLD. I have tried adding an if statement after the second for loop to determine if the columns sum, a[i], is > THRESHOLD, and then printing the column:

awk '
  BEGIN {FS=OFS=" "}
  NR==1 {print}
  NR>1  {for (i=1;i<=NF;i++) if ($i < 5 && $i > 0) a[i]+=1}
  END   {for (i=1;i<=NF;i++) if (a[i] < THRESHOLD) printf $i
}' snp_fake2.txt > tmp.txt`

But when I run this the script does not output the entire column, only a single number. How can I print the entire column instead of just the single value?

  • 1
    (1) Your use of the word “sum” is misleading.  You are dealing with the count of values that meet criteria.  (2) I believe that I sort-of understand what you want, but it would help if you would show an example of input and the output that you want to get from it. … … … … … … … Please do not respond in comments; edit your question to make it clearer and more complete. – Scott Feb 8 at 0:11
0

AWK processes the file one line at a time. It has no memory of previous lines. The END rule executes after the last line is processed. At this point AWK cannot print all the entries in column $i because it only knows a single value for column $i: the one from the last line.

Your goal requires two passes of the file: one to calculate the column sum, and a second to print out the entire column (for the appropriate columns). To do so, you could write a shell script that calls awk to calculate the sums, and then calls awk (or something else) to print the columns.

0

If I understood right, one way is to use two dimensional array. It works with GNU awk.

echo -e '1 4 7\n2 5 8\n3 6 9' | awk '
{ for (i=1;i<=NF;i++) {
        field[i][NR]=$i
        if ($i < 5 && $i > 0) {
            a[i]+=1
            }
        }
}
END {
    for (i in a) {
        if (a[i] > 2) {
            for (j in field[i]) print field[i][j]
            }
        }
}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.