11

I'd like the output of the uniq command to be comma separated, so that instead of:

     30 hello
     31 world
     36 hey_there
    142 i_am_bigest

I'll get:

30,hello
31,world
36,hey_there
142,i_am_biggest

My input has no spaces, but just using sed or tr can be a problem since the number of leading spaces varies according to the number of decimal digits in the count.

Jens
  • 69,818
  • 15
  • 125
  • 179
eran
  • 14,496
  • 34
  • 98
  • 144
  • This Q. specifically looks like changing the output of `... | sort -rn | uniq -c`. – agc Jan 16 '19 at 19:44

5 Answers5

21

Pipe the output to

sed -e 's/^ *//;s/ /,/'

This first removes the leading spaces (^ *) then replaces the first space with a comma.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
4

man uniq (at least on Mac OS X, aka BSD) does not give any way to handle that. Your best bet is probably sed:

... |
uniq -c |
sed 's/^ *\([0-9][0-9]*\) /\1,/'

The output from uniq -c consists of some blanks, a number, a blank, and the input string.

The basic idea is that the sed script looks for an arbitrary number of blanks, a number and a blank, and replace it by the number and a comma. Looking at the POSIX specification for uniq, the output is not supposed to have leading blanks (the printf() format should be "%d %s"), but leading blanks are normal in practice (for small enough repeat counts; on Mac OS X, the output printf() format is effectively "%5d %s").

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

pipe the output to :

perl -lane '{print join ",", @F}'
Vijay
  • 65,327
  • 90
  • 227
  • 319
  • As with the `awk`-based solution, this does not work well when the input lines have multiple fields according to Perl. For example, with sorted input consisting of 4 lines containing `aaa aaa aaa aaa` and 5 lines containing `aba aba aba aba`, the ouptut from your script (after `sort` and `uniq -c`) is two lines: `4,aaa,aaa,aaa,aaa` and `5,aba,aba,aba,aba`; note the extra (and unwanted) commas. – Jonathan Leffler Jun 10 '13 at 06:43
1
  1. Using printf works:

    xargs -L 1 printf '%s,%s\n' < file
    
  2. Using bash:

    printf '%s,%s\n' $(<file)
    
  3. In a POSIX shell this would also work:

    printf '%s,%s\n' $( ...various commands... | uniq -c )
    
agc
  • 7,973
  • 2
  • 29
  • 50
0

Using @nneonneo's answer, I wrote this function and added it to my .bashrc:

uniqc(){
    uniq -c |sed -e 's/^ *//;s/ /,/' 
}

Usage, instead of doSomething | uniq -c, do:

doSomething | uniqc
Isin Altinkaya
  • 439
  • 4
  • 11