1

I have a data file which a part of it looks like this:

4 1
5 2
1 2
3 1
1 1
1 2
1 1
1 1
2 1
2 1

I want to count similar rows and put my counts in a third column like this:

    4 1 1
    5 2 1
    1 2 2
    3 1 1
    1 1 3
    2 1 2

Any suggestion please?

1
  • 1
    You can do this a few ways: sort | awk once you are sorted you can assume that once you see an input change you can print the total. Using perl you can build a hash table where each line is a key and the value is how many times you have seen it and then at the end of input you can print out the map; try to get the key if it fails add it with value 1, if it succeeds add 1 to the value. Commented Jan 21, 2020 at 21:46

2 Answers 2

3

Here's one way. Sort the file, then get counts using uniq -c, then use awk to flip the field order around.

$ sort file.txt | uniq -c | awk '{ print $2,$3,$1 }'
1 1 3
1 2 2
2 1 2
3 1 1
4 1 1
5 2 1
$

And a second way, using pure awk.

$ awk '{ x[$0]++ } END { for(a in x) { print a,x[a] } }' file.txt
1 1 3
1 2 2
4 1 1
2 1 2
5 2 1
3 1 1
$

Third way, perl. Bit hacky/lengthy, so waiting on someone to show a more elegant approach.

$ perl -nle '$a{$_}++;END{for(keys %a) { print $_," ",$a{$_} } }' <file.txt
3 1 1
1 2 2
5 2 1
1 1 3
2 1 2
4 1 1
$
0

Using Miller:

$ mlr --nidx uniq -g 1,2 -c file
4 1 1
5 2 1
1 2 2
3 1 1
1 1 3
2 1 2

or, equivalently

mlr --nidx count-distinct -f 1,2 file

Unlike awk arrays or perl hashes, Miller appears to preserve the "seen order" of the keys - but I don't know if that's guaranteed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .