シェル芸で特にスペース区切り等のない文章中から使われている文字列を集計する

ここでそんな感じの処理について見かけたので、シェル芸で文章中からの単語の集計(例:「ABCDandABCDorABCDsoABCD」だと、ABCDが4回使われているなど)をシェル芸で一発でできないかなと思ったので、試しにやってみることにした。
まず、文章の中から単語を取得する必要があるのだが、形態素解析だと対象が文章ではなくバラバラな羅列だった場合に使えないので、文章中から1文字づつ範囲をずらして文字を抽出し、それを集計することで使われている文字列を取得することにした。

で、ちょっと長いけど以下のようにすることで、複数回出現した文字列の組み合わせが取得できる。

echo ABCDandABCDorABCDsoABCD|sed 's/ //g'|(A="$(cat)";seq 2 $(wc -c<<<"$A")|xargs -I@ bash -c 'echo "'$A'"|sed -e"p;1s/^.//g;"#{2..@}|(X=$(cat);echo "$X"|grep -Eo .{$(wc -l<<<"$X")})'|sort -u|xargs -I@ bash -c 'echo "'$A'"|grep -o @')|uniq -cd|awk '{print length($2),$0}'|sort -k1nr|awk '
{print $2,$3}'
blacknon@BS-PUB-UBUNTU-01:~$ echo ABCDandABCDorABCDsoABCD|sed 's/ //g'|(A="$(cat)";seq 2 $(wc -c<<<"$A")|xargs -I@ bash -c 'echo "'$A'"|sed -e"p;1s/^.//g;"#{2..@}|(X=$(cat);echo "$X"|grep -Eo .{$(wc -l<<<"$X")})'|sort -u|xargs -I@ bash -c 'echo "'$A'"|grep -o @')|uniq -cd|awk '{print length($2),$0}'|sort -k1nr|awk '{print $2,$3}'
4 ABCD
4 ABC
4 BCD
4 AB
4 BC
4 CD
blacknon@BS-PUB-UBUNTU-01:~$ echo うんことうんこかうんこでうんこ|sed 's/ //g'|(A="$(cat)";seq 2 $(wc -c<<<"$A")|xargs -I@ bash -c 'echo "'$A'"|sed -e"p;1s/^.//g;"#{2..@}|(X=$(cat);echo "$X"|grep -Eo .{$(wc -l<<<"$X")})'|sort -u|xargs -I@ bash -c 'echo "'$A'"|grep -o @')|uniq -cd|awk '{print length($2),$0}'|sort -k1n
r|awk '{print $2,$3}'
4 うんこ
4 うん
4 んこ
Sponsored Links

で、これでとりあえず動くからいいかと思ってたのだが、@ebanさんがjqコマンドを使ってTwitter上にポストできるくらいに短くされていた。
(jqコマンド、こんなteeみたいな挙動してるのか…)


これを参考に、bashで変数展開を使ってみたところ、もうちょい短く書くことができた。

echo ABCDandABCDorABCDsoABCD|(i=$(cat);l=${#i};seq -f '(i='$i';l='$l';x=%g;eval eval "echo\ \\\${i:$x:{1..$l}}\;")' 0 $l|bash|uniq)|sort|uniq -cd|awk 'length($2)>1{print $0,length($2)}'|sort -k3nr|awk NF--
blacknon@BS-PUB-UBUNTU-01:~$ echo ABCDandABCDorABCDsoABCD|(i=$(cat);l=${#i};seq -f '(i='$i';l='$l';x=%g;eval eval "echo\ \\\${i:$x:{1..$l}}\;")' 0 $l|bash|uniq)|sort|uniq -cd|awk 'length($2)>1{print $0,length($2)}'|sort -k3nr|awk NF--
4 ABCD
4 ABC
4 BCD
4 AB
4 BC
4 CD

 


Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

*