Is there a way to summarize second fields for single identifiers using awk and replace output with nonnumbers?

Viewed 89

I have a .txt file:

a 10
b 13
a 2
b 5
c 1

Where the first column is for the identifiers, and the second one is for the values.

If I wanted to go over the file using awk and sum up the numbers in the second column for each item in the first column, then replace it with * before printing so the output is as below, how would I go about that?

a : **
b : **
c : *

So that the number of stars is equal to the number of digits in the number (12 -> **, 18 -> **, 1 -> *)

awk '{gsub("12", "**"); print}' test.txt

I've tried this, but of course it's not the right solution. Open for any advice.

3 Answers

You may use this awk:

awk '{sums[$1] += $2} END {for (i in sums) {
gsub(/./, "*", sums[i]); print i, ":", sums[i]}}' file

a : **
b : **
c : *

Could you please try following, written and tested with shown samples.

awk '
FNR==NR{
  arr[$1]+=$2
  next
}
($1 in arr){
  gsub(/./, "*", arr[$1])
  print $1, ":", arr[$1]
  delete arr[$1]
}
' Input_file Input_file

To get the digit length of a number call length on it, e.g.:

print length(12)

Output:

2

Here is an example that works with GNU awk using printf's variable width and precision pattern (%*s):

parse.awk

{ h[$1] += $2 }
END {
  for (k in h) {
    padding = sprintf("%*s", length(h[k]), "")
    gsub(/ /, "*", padding)
    print k " : " padding
  }
}

Run it like this:

awk -f parse.awk infile

Output:

a : **
b : **
c : *
Related