labunix's blog

labunixのラボUnix

USP友の会の勉強会(私の反省会)

 

 

 
■USP友の会の勉強会に行ってきました。
 色んな反響があったようですが、特にここでは述べません。

 日本唯一の #シェルスクリプト コミュニティ「USP友の会」がお送りするシリーズもの勉強会の第4弾!(最終回:DFDのお話)
 http://www.zusaar.com/event/295001

■反省点

 後述の「3/7」はまだ解けてない。
 行列を入れ替えて、コメント化したようにマージしようかと思ったけれど、なんか違う。。。
 頭が凝り固まっているのかも知れない。。。

 単語のソートはストリームに出来ない(逐次実行)箇所なので、
 ループは致し方ない代わりにそこにまとめてしまう。

 「3/7」をループしないようストリーム化することにとらわれすぎているのかも知れない。。。
 これは時間を置いた方が良さそう。。。

 突っ込みがあれば是非。。。

■DFDの話を私がするとややこしくなるし、その辺は勉強会に出席して各自で温度を感じてもらいたいものですが、
 私の感覚で言うと、以下になる。

 「逐次実行とストリームを上手く組み合わせて、並列処理も見据えたスクリプトを書こう」

■お題
 単語の出現頻度を得るスクリプトは結構よくあると思いますが、
 今回はアナグラムの一覧を得るスクリプトを書くことに。。。
 「0/7」は準備運動として出された例題処理をそのまま埋め込みました。。。

 アナグラム
 http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%8A%E3%82%B0%E3%83%A9%E3%83%A0

■以下のような単語ファイルがあったとして。。。

$ cat dict.txt
pans
pots
opt
snap
stop
tops

■使い方はUsageの通り。一応書きます。

$ chmod +x usp_dfd.sh
$ ./usp_dfd.sh dict.txt

■以下のようなスクリプトを書こうと。。。
 ※「# cat;unset list;exit 0」をアンコメントすれば各ステップを出力できる。

$ cat usp_dfd.sh
#!/bin/bash

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

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

■実行結果

□0/7

$ ./usp.sh dict.txt
pans
pots
opt
snap
stop
tops

□1/7

$ ./usp.sh dict.txt
anps  pans
opst  pots
opt  opt
anps  snap
opst  stop
opst  tops

□2/7

$ ./usp.sh dict.txt
anps  pans
anps  snap
opst  pots
opst  stop
opst  tops
opt  opt

□3/7

$ ./usp.sh dict.txt
anps  pans
anps  snap
opst  pots
opst  stop
opst  tops
opt

※本来は、以下を得る。。。

psns snap
pots stop tops
opt

□4/7

$ ./usp.sh dict.txt
2 4 psns snap
3 4 pots stop tops
1 3 opt

□5/7

$ ./usp.sh dict.txt
3 4 pots stop tops
2 4 psns snap
1 3 opt

□6/7

$ ./usp.sh dict.txt
pots stop tops
psns snap
opt

□7/7

$ ./usp.sh dict.txt
pots stop tops
psns snap
opt