I've got a file of ~1-2 million lines that I'm trying to reduce down by counting duplicate groups of lines, preserving order.
uniq -c
works okay :
$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' | uniq -c
4 foo
4 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz
In my use-case (but not in the following foo-bar-baz example), counting pairs of lines is ~20% more efficient, and looks like :
$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' \
| sed 's/^/__STARTOFSTRINGDELIMITER__/' \
| paste - - \
| uniq -c \
| sed -r 's/__STARTOFSTRINGDELIMITER__//; s/__STARTOFSTRINGDELIMITER__/\n\t/;'
2 foo
foo
2 bar
bar
1 baz
foo
1 bar
baz
1 foo
bar
1 baz
foo
1 bar
baz
1 foo
bar
1 baz
(That format is acceptable to me.)
How can I reduce duplicate groups of arbitrary numbers of lines (well, keeping a sane buffer count like 2-10 lines) down to a single copy + count of them ?
Following the above example, I would want output similar to :
4 foo
4 bar
1 baz
4 foo
bar
baz
foo
followed bybar
occur 5 times.foo
followed bybar
4 times ? (The first two sets of four each). You would be correct then, yes, and either output would be acceptable for me (eitherfoo
x4 thenbar
x4, or (foo
,bar
) x4). I assume it would depend on the buffer length - 10 lines of buffer would produce the latter, less than 8 lines of buffer would produce the former. It's not really an issue as you say, just a consideration.