labunix's blog

labunixのラボUnix

USP友の会勉強会(6/10)のその後。「背伸びしないスクリプトを書く」

 

 

 
 前回は悩んだ。でも悩んで答えが出ないよりはとりあえずでも答えは出した方がよいと思う。
 というわけで、流れを一旦止めちゃえ版です。
 また、「tr」の使い方等、若干修正しました。

$ tr -cs 'A-z' '\012' 

■参考

 USP友の会の勉強会(私の反省会)
 http://labunix.hateblo.jp/entries/2012/06/11

 7.2 豊富な文字処理用ツール - パターン抽出,文字列変換 -
 http://cai.cs.shinshu-u.ac.jp/sugsi/Lecture/HowToUnix/7-2.html

 Find anagrams for
 http://wordsmith.org/anagram/

 Toto Anagram Solver
 http://www.totoanagramsolver.com/

 find anagrams
 http://golf.shinh.org/p.rb?find+anagrams

■勝手に仕様を追加。
 アナグラムが見つかった(2つ以上の単語があった)場合のみ出力。
 以下のように「opt」が無くなる。

$ ./usp_dfd.sh dict.txt
pots stop
pans snap

■決して速い訳ではないが、単語として、アナグラムが存在する上位10位は表示できる。
 というか10個も無いw。

$ w3m -dump "http://golf.shinh.org/p.rb?find+anagrams" > dict2.txt
$ time ./usp_dfd.sh dict*
flogscript golfscript
canter carnet
enlist listen
post pots
form from
pans snap
opt top

real    0m7.974s
user    0m13.825s
sys     0m4.492s

■先頭の10の制限という仕様をまた勝手に変更して、
 短編小説で有名なO Henlyの「The Last Leaf」で探す。
 さすが、文学の巨匠は短編でも結構出てきますね。。。

$ time ./usp_dfd.sh dict3.txt
night thing
there three
ache each
dear read
east seat
mean name
mite time
site ties
der red
how who
its sit
now won
no on

real    0m27.004s
user    0m47.107s
sys     0m15.217s

■スクリプトは以下に出しておきます。

$ cat usp_dfd.sh
#!/bin/bash

if [ "$#" -lt 1 ];then
  echo "Usage $0 [ text_file_name ]"
  exit 1
fi

# 指定されたファイルを取り込み、英小文字のみ取り込む
cat "$@" | tr -cs 'A-z' '\012' | tr 'A-Z' 'a-z' | \
sed s/"\[\|\]\|\ \|_"/"\n"/g | \
\
# 単語をソートして出来る文字を加える
for list in `xargs`;do \
  # 単語の並べ替え アルファベット順
  echo -n "$list" | sed s/"."/"&\n"/g | sort | \
    xargs echo -n | sed s/" "//g
  # 元の単語
  echo " $list"
done | sort | uniq > temp.txt;unset list
# cat;unset list;exit 0
#
# 先頭の文字列が等しい単語をまとめる
# (行の中に空白で区切ってまとめる)
for list in `awk '{print $1}' temp.txt | uniq`;do \
  grep "^$list " temp.txt | awk '{print $2}' | xargs echo -n;echo
done | grep " " | \
# cat;unset list;exit 0
#
#cat;unset list;exit 0
#
# 単語数と単語の文字数を先頭に加える
\
awk '{print length($1),NF,$1,$2}' | \
# cat;unset list;exit 0
#
# 単語数と単語の文字数の降順に並べ替える
sort -k 1nr -k 2nr | \
# cat;unset list;exit 0
#
# 付け加えた単語数と文字数を取り除く
sed s/"^[0-9]* [0-9]* "//g | \
# cat;exit 0
#
# 先頭の10行を表示する
#head -n 10 | \
cat;unset list;exit 0