Why uniq -c output with space instead of \t?
Asked Answered
T

7

8

I use uniq -c some text file. Its output like this:

123(space)first word(tab)other things
  2(space)second word(tab)other things

....

So I need extract total number(like 123 and 2 above), but I can't figure out how to, because if I split this line by space, it will like this ['123', 'first', 'word(tab)other', 'things']. I want to know why doesn't it output with tab?

And how to extract total number in shell? ( I finally extract it with python, WTF)

Update: Sorry, I didn't describe my question correctly. I didn't want to sum the total number, I just want to replace (space) with (tab), but it doesn't effect the space in words, because I still need the data after. Just like this:

123(tab)first word(tab)other things
  2(tab)second word(tab)other things
Tenorrhaphy answered 26/7, 2012 at 13:29 Comment(2)
A tab is not a space so awk is correct.Hysteric
@Tichodroma no, you didn't follow me. I mean if I split line by space, I can't get data after correctly.Tenorrhaphy
A
9

Try this:

uniq -c | sed -r 's/^( *[^ ]+) +/\1\t/'
Anglicism answered 26/7, 2012 at 13:49 Comment(1)
That's I wanted! Thank you all guys. I forget I can lose /g at last.Tenorrhaphy
A
8

Try:

uniq -c text.file | sed -e 's/ *//' -e 's/ /\t/'

That will remove the spaces prior to the line count, and then replace only the first space with a tab.

To replace all spaces with tabs, use tr:

uniq -c text.file | tr ' ' '\t'

To replace all continuous runs of tabs with a single tab, use -s:

uniq -c text.file | tr -s ' ' '\t'
Apical answered 26/7, 2012 at 13:56 Comment(0)
D
1

You can sum all the numbers using awk:

awk '{s+=$1}END{print s}'
Disease answered 26/7, 2012 at 13:37 Comment(0)
L
0
$ cat <file> | uniq -c | awk -F" " '{sum += $1} END {print sum}'
Lassiter answered 26/7, 2012 at 13:38 Comment(3)
Look askance at any occurrence of cat one-file; it can be replaced by I/O redirection. There's also the UUOC Award, even.Delay
Another nice thing about Unix how you can keep your code clean and well-structured using pipes. Of course you can use a redirect instead of cat file, but it's perfectly reasonable to do exposition / explanation in that form (and even production coding too), because in practice it will often end up being a more complex command that kicks things off. The performance argument is specious too; most of the time it doesn't actually matter, and you're better off optimizing for readability.Carbylamine
Yeah, I usually use it as a placeholder for some other process that prints to stdout when giving examples online like this.Lassiter
C
0

One possible solution to getting tabs after counts is to write a uniq -c-like script that formats exactly how you want. Here's a quick attempt (that seems to pass my minute or so of testing):

awk '
(NR == 1) || ($0 != lastLine) {
    if (NR != 1) {
        printf("%d\t%s\n", count, lastLine);
    }
    lastLine = $0;
    count = 1;
    next;
}
{
    count++;
}
END {
    printf("%d\t%s\n", count, lastLine);
}
' yourFile.txt
Carbylamine answered 26/7, 2012 at 14:3 Comment(0)
C
0

Another solution. This is equivalent to the earlier sed solution, but it does use awk as requested / tagged!

cat yourFile.txt \
    | uniq -c \
    | awk '{
        match($0, /^ *[^ ]* /);
        printf("%s\t%s\n", $1, substr($0, RLENGTH + 1));
      }'
Carbylamine answered 26/7, 2012 at 14:49 Comment(0)
R
0

Based on William Pursell answer , if you like Perl compatible regular expressions (PCRE) maybe a more elegant and modern way would be

perl -pe 's/ *(\d+) /$1\t/'

Options are to execute (-e) and print (-p).

Radcliff answered 1/4, 2020 at 3:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.