順序を維持しながら繰り返し行グループを数えて減らそうとする約1〜2百万行のファイルがあります。
uniq -c
うまく動作します:
$ 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
私のユースケースでは(しかし、以下のfoo-bar-bazの例ではありません)count右ライン効率は以下のように約20%向上します。
$ 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
(この形式を受け入れることができます。)
任意の行(2〜10行などの合理的なバッファ数を保持)の重複グループを単一のコピー+行数に減らすにはどうすればよいですか?
上記の例では、次のような出力が必要です。
4 foo
4 bar
1 baz
4 foo
bar
baz
答え1
ベンチマークするのに十分なデータセットはありません。試してみてください:
$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' | awk 'NR == 1 {word=$0; count=1; next} $0 != word {print count,word; word=$0; count=1; next} { count++ } END { print count,word }'
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
mawk
代替を使用すると、awk
パフォーマンスが向上する可能性があります。