とき

USP MAGAZINEUSP MAGAZINE 2014 winter Vol.11

コ ー ド は 思 い 立 っ た 瞬 間 に 書 け 。こ た つ は 風 邪 ひ く 前 に 出 せ 。
ISSN 2187-9664

USP
MAGAZINE
20int14er

W
500Yenfor the sophisticated shell scripters

突撃！隣のコードレビュー会
新連載

2014 winter発行人 當仲寛哲
発行・発売 有限会社ユニバーサル・シェル・プログラミング研究所〒105-0003 東京都港区西新橋 3-4-2 SS ビル 3 階 電話 03-3432-1174 発行日 2013 年 12 月 20 日

特集

熊野憲辰
「未来に活きる！
現場で使える！

データモデリング」
すすたわり氏に訊く、技術者哲学

好評連載

定価 500 円（本体価格 476 円）

大岩元「今私たちは何を学ぶべきか」
UNIXネイティブの電子工作塾「はんだごてとキーボード」
Vol.11

Artwork created by Koji Ishizuka. © 2012 Zie's Bank .Co,. LTD All rights reserved.

USPMAG201312_h1-4_cs55.indd

1

2013/12/27

9:15:48

From Editor
今号の特集で取り上げた USP のコードレビュー会やコマンド研究会では、様々なエンジニアの異なる立場や環境、考え方がぶつかり合います。その中で、お互いに他人の方法や思想を自分のものとして受け入れ、新たなものを作り出していくのです。
マイク・ガンカーズの著書『UNIX という考え方』に、「ソフトウェアの梃子を有効に活用せよ（Usesoftware leverage to your advantage.）」という定理が示されています。
ソフトウェアの梃子（leverage）とは、他人が書いたプログラムを自分のプログラムの中で利用すること。
どんなに優秀なプログラマでも、1 人で書けるコードには限界があるが、すでにあるプログラムをうまく利用すれば、もっと多くのプログラムを書けるということです。
自分が作ったものとは異なる「他人が作ったもの」を受け入れる、このことに抵抗する人は多いでしょう。
ガンカーズは「独自技術症候群」と呼んでいます。技術に限らず、自分とは異質な「新しい」ものを自分の中に受け入れることは難しいことです。
しかし、多くの人がソフトウェアの梃子を活用して作り上げた「UNIX」が、素晴らしい成果を収めていることを思い出せば、あなたにもきっと、新しいものを受け入れる “ 勇気 ” が出てくるでしょう。
USP MAGAZINE 編集部

Contents
特集

突撃！隣のコードレビュー会（一部より抜き） …………………………………………… 3

スズラボ通信新連載

第3回

すずきひろのぶ …………………………………………………………………………… 17

未来に活きる！現場で使える！データモデリング熊野憲辰 ………………………………………………… 22

シルネン・ブヤンジャルガルの自立への挑戦、情報整理技術の開拓

漢の UNIX

第8回

第3回…………………………………… 24

後藤大地 ……………………………………………………………………………………………… 28

今私たちは何を学ぶべきか

第 11 回大岩元 …………………………………………………………………… 32

TechLION 再録 北の大地でエンジニアが語る ローカルから広まる新たなつながり……………………… 34
UNIX ネイティブの電子工作塾
中小企業手作り IT 化奮戦記

第三講

第9回

大野浩之 ……………………………………………………………… 40

菅雄一 …………………………………………………………………… 56

すすたわり氏に訊く、技術者哲学……………………………………………………………………………… 59
ユニケージエンジニアの作法

第9回………………………………………………………………………… 63

TEX の強みはプログラムにあり TUG2013 レポート

シェルスクリプト大喜利
Tech 数独………………………………………………………………… 67

第 11 回 ……………………………………………………………………………… 69…………………………………………………………………………………………………………………………… 74

仕事の原点 シェル魔人／ 編集後記 ………………………………………………………………………………………………… 75※「うにっくすなやつら」、「IT 美女図鑑」はお休みします。
※ 薄字の記事はよりぬき版には収録されていません。是非正式版をお求めください。

2

USP MAGAZINE 2014 winter

USPMAG201312_h1-4_cs55.indd

2

2013/12/27

9:15:50

特集

あなたのコード、 見せてください。
USP MAGAZINE 編集部

こんにちは、はじめまして。私は、全国津々浦々、面白いプロ
グラムコードがあると聞き付ければ見せてもらいに訪問する、
突撃レポーターの「ソースコード・ヨメスケ」です。
さて今日は、シェルスクリプトのコードレビュー会を開催している集団がいるということで、そちらにおじゃました時の模様をレポートします。実はレビュー会の後、コマンド研究会という会議も開かれていまして、そちらもあわせて紹介します。

USPMAG 201312.indb

3

2013/12/27

14:26:04

1. 朝のシェルスクリプトコードレビュー会
コードレビュー形式の勉強会。参加したことありませんか？

あれって面白いですよねー。十人十色なスタイルのソースコードにお目に掛かれますし、予想もしていなかった鋭いツッコミが交わされたりしてスリリングですよね。今回、シェルスクリプトのコードレビュー会を開催しているところがあるという情報を得たので突撃してきました。さて、皆さんどんなコード書いているんでしょうか！

コードや意見を聞くことはとても刺激的。そして自分

コードレビューはおもしろい
コードレビューといえば、制作されたプログラム
コードを見返すことで、見過ごされてしまった動作の誤りや脆弱性を発見したり、効率や性能・堅牢性を上げるため、あるいはメンテナンス性・可読性を向上させるための修正点の洗い出しなど、現在のコードの品
質を向上させるための作業です。

の書くコードもどんどん進化していきます。レビュー会に参加し続けるうち、自分の書くコードががらっと変わっていたことに気づき、驚く人もいます。
コードレビュー会、職場や各地の勉強会など、開催されるとあらば是非参加してみてはいかがですか？

シェルスクリプトの
コードレビュー会 !?

しかし向上するのはコードの品質だけではありませ

USP 研究所では毎週金曜、技術部隊が集まって、
コーん。コードレビューに参加したプログラマーのスキル

ドレビュー会が開催されているそうです。シェルプロも向上していきます。ゆえに、IT 系の勉強会などでもグラミングが社名にもなっているだけあって、扱う

コードレビュー会が企画されることがあります。

コードはシェルスクリプトがほとんど。ビジネスシス

勉強会としてのコードレビュー会は、自分の書いた
ソースコードを互いに見せ合いながら「そのやり方いテムで使用するシェルスクリプトの例を用意し、それらについて議論を交わしているそうです。

いね！」とか「いや、それはこー書くでしょ」などとJavaScript や Ruby, Python などの他の LL 言語のレ

屈託ない意見が交わされたりします。レビューをする

ビュー会はよく耳にしますけど、シェルスクリプトの時も、される時も、その様子を観覧する時も、あれが

コードレビュー会とは珍しい！ということで、社内の実に面白いのです。

レビュー会ではあるものの取材させてもらい、今回のまず、ソースコードのパッと見が十人十色で全然違

特集記事にすることにしました。

います。いくら記述ルールを統一していても、細部まで見ると書く人の流儀が見えてきます。なので、同じことをやるにしても実現方法・アルゴリズムが様々。
「そんなふうにやるのか！頭いいな！」と自分では成し得なかった発想に何度も何度も感心します。
逆に、ツッコミを入れたくなることもしばしば。
「その書き方はわかりづらいよね」とか「あれ、そこ矛盾してない？」などなど。自分ではなかなか気づかなかった事でも、他人が見ればあっと言う間に気付いたりします。時には「指摘を受けることは承知の上で、別のメリットを得るために敢えて書いている」などということもあり、それはそれでとても奥が深いです。
どんな言語であっても、コードレビュー会で様々な

4▲シェルスクリプトのコードレビュー会とは珍しい

USP MAGAZINE 2014 winter

USPMAG 201312.indb

4

2013/12/27

14:26:06

特集― 突撃！隣のコードレビュー会 ～ あなたのコード見せてください[1] データ検索用 CG I Web フロントエンド
お一人目は USP 技術研究員の大内さん。今回発表したプログラムは、商品在庫を問い合わせる Web ア
プリケーションプログラムの例だそうです。
ここではその中から、ユーザーの Web ブラウザー

部分のシェルスクリプト（リスト 1）を紹介します。
（検

索ルーチン本体や結果表示などは、別のシェルスクリ
プトに分け、一つのプログラムが長くならないようにしているそうです）

から検索等のリクエストを受け付けるフロントエンド
リスト 1. 返品データ入力検索：フロントエンド CGI
1 #!/bin/ush -xve
2 #3 # システム名    :********************
4 # サブシステム名:********
5 # 業務名        :****
6 # プログラム名  :本部／返品データ入力検索CGI
7 # 概要          :***********************************
8 # 詳細          :9 # 備考(Usage)   :*****************************
10 # シェル名      :***_HENPIN_DATA_NYUURYOKU.CGI
11 # 作成日        :2013/6/28
12 # 会社名        :USP-LAB
13 # 作成者        :T.Ouchi
14
15 #///////////////////////////////////////////////////////////////////////////////
16 # 初期設定
17 #///////////////////////////////////////////////////////////////////////////////
18
19 #-------------------------------------------------------------20 # 変数の定義
21 #-------------------------------------------------------------22
23 # 走行ログの記録
24 HOME="/home/**"25 logd="${HOME}/AP/LOG"                                                 # ログディレクトリ
26 logf="${logd}/LOG.$(basename $0).$(date +%Y%m%d)_$(date +%H%M%S)_$$"  # ログファイル名
27 echo  "${logf}" > /dev/null 2>&1
走行ログ *2 をとる場合、
28 log 2> ${logf}
bash では “exec 2>${log}” などと書くが、29
ush ではこのように書く。
30 # PATHの定義
31 PATH=/home/UTL:/home/TOOL:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}
32 LANG=ja_JP.UTF-8
環境変数を定義する場合でも
ush では export を使わない。
33
34 HOSTNAME=$(hostname -s)
35 tmp="/tmp/$$-$(basename $0)_$(date +%Y%m%d%H%M%S)"          # 一時ファイル
36 cgid=${HOME}/AP/MCS_DENPYOU/CGI                        # CGIディレクトリ
37 semd=$｛HOME｝/SEMAPHORE
ワークエリア ( 作業用ファイル )38のプレフィックス定義
39 #---- 処理日時 ---40 sdaytime=$(date +%Y%m%d%H%M%S)
41
42 #-------------------------------------------------------------43 # エラー処理（システムエラー系）
44 #-------------------------------------------------------------45 cgi_err="**********"               # 予期せぬエラー
46 #47 err ERROR_EXIT(){ush の場合、エラー処理関数は、関数名の前に “err” を記述する
48

5

USPMAG 201312.indb

5

2013/12/27

14:26:08

1. 朝のシェルスクリプトコードレビュー会
49   # エラーのロギング
50   touch $semd/$(basename $0).$HOSTNAME.ERROR.$sdaytime
51
52   cat <<ETX | nkf -W -sxLw
53 Content-type: text/html; charset=Shift_JIS
54
55 "${cgi_err}","1","EOT"56 ETX
57   # 本ハンドラに飛び込むとエラーステータスを返す
58   exit 1
59 }60
61 #///////////////////////////////////////////////////////////////////////////////
62 # 処理部
63 #///////////////////////////////////////////////////////////////////////////////
64
65 #------------------------------------------------------------------------------66 # 画面からのPOST情報をファイルに無変換保存
67 #------------------------------------------------------------------------------68 dd bs=${CONTENT_LENGTH}>${tmp}-ifdata
ブラウザーから送られた
POST/MIME 形式の取得
69
70 #------------------------------------------------------------------------------71 # 入力データの切り出し
72 #------------------------------------------------------------------------------73 ${cgid}/***_HENPIN_DATA_NYUURYOKU.INITGET  ${tmp}-ifdata          > ${tmp}-flddata74取得した POST/MIME 形式を
Tukubai の「name 形式」へ変換
75 #-------------------------------------------------76 # チェック処理
77 #-------------------------------------------------78 ${cgid}/***_HENPIN_DATA_NYUURYOKU.CHECK ${tmp}-flddata > ${tmp}-check79
取得したデータの80 if [ -s ${tmp}-check ] ; then
各種正当性を検査する
81   #-------------------------------------------------検査不合格なら82   # 表示用データ作成（エラー）
エラー画面表示83   #-------------------------------------------------84   ${cgid}/***_HENPIN_DATA_NYUURYOKU.DISPLAY ${tmp}-check85
86 else87
ブラウザーのリクエストに基づく
実際の検索を行うシェルスクリプト88   #----------------------------------------------------------------------------（リスト２）89   # データ検索90   #----------------------------------------------------------------------------91   ${cgid}/***_HENPIN_DATA_NYUURYOKU.SEARCH ${tmp}-flddata ${sdaytime} $$         > ${tmp}-search
92
93   #----------------------------------------------------------------------------94   # データ表示
95   #----------------------------------------------------------------------------96   ${cgid}/***_HENPIN_DATA_NYUURYOKU.DISPLAY ${tmp}-search
検索結果を
97
画面に表示
98 fi
99
100 #-------------------------------------------------101 # 正常時のロギング
102 #-------------------------------------------------103 touch $semd/$(basename $0).$HOSTNAME.END.$sdaytime
104
105
106 #///////////////////////////////////////////////////////////////////////////////
107 # 終了
108 #///////////////////////////////////////////////////////////////////////////////

6

USP MAGAZINE 2014 winter

USPMAG 201312.indb

6

2013/12/27

14:26:08

特集― 突撃！隣のコードレビュー会 ～ あなたのコード見せてください
109 rm -f ${tmp}-* > /dev/null
110 exit 0

ワークエリア ( 作業用ファイル )の全削除■■プログラムのポイント
このプログラムで注目してもらいたいポイントは、独自シェル /bin/ush(*1)に対応させるための記述上の注意点とのことです。
走行ログ (*2) の出力には exec ではなく独自内部コマ
ンドの log を使う点、環境変数の設定のしかた、エラー
処理関数の定義には予約語 err を付ける点等が異なり
ます。

■■解説
ush 自体は OSS として公開されているシェルではないため、「ush 使用時の注意点」に関しては多くの読者にとって関心の及ばないところではあります。しかし、このプログラムにはシェルプログラミングを実践するうえで参考になる記述がいくつか見られます。
一部は連載「ユニケージエンジニアの作法」でも紹介してきたことですが、・上から下へ素直に読めるプログラミング*1 ush( ゆーしぇる ) とは
FreeBSD の /bin/sh (ash) を元にし、そこから fork す
る形で USP 研究所が独自開発しているシェル。
ash は、Linux の多くのディストリビューションで標準とされる Bash に比べ、機能がシンプルなぶん高速に動く。そこで、そのメリットをさらに増すためユニ
ケージプログラミング上で不要な機能を徹底的に削ぎ落とし、更なる高速化を図っている。

*2 走行ログとは
sh -xv などと記述して、シェルスクリプト実行ステッ
プを全てログファイル出力したものの通称。
デバッグ時や障害発生時に素早く対応できるように、
ユニケージプログラミングにおいては通常必ず行う。

■■検索ルーチン
2 本目のリストは 1 本目に紹介したフロントエンド

・冒頭には連絡先までわかるコメント

から呼び出される検索ルーチンのシェルスクリプトの・POST リクエストの受け取り方一部です。検索用の CGI スクリプトということで、肝・走行ログの取り方

心の検索部分はどうなっているのか気になったため、などです。

見せてもらいました。
（リスト 2）

リスト 2. 返品データ入力検索：検索（抜粋）129                       :130 cat ${lv4d}/${tenpocd}/HENPIN_DATA |131 #  1:店舗コード        2:店舗名        3:データ作成日付      4:データ作成時刻 5:SEQ
132 #  6:事業会社コード    7:事業会社名    8:商品コード          9:商品名         10:数量
133 #  11:返品先           12:返品先名     13:原単価             14:売単価        15:伝票データ取込区分
134 #  16:取込チェック結果 17:エラーフラグ 18:伝票作成ステータス 19:本部店舗区分  20:担当者
135 #  21:税区分           22:更新フラグ   23:更新日              24:ユーザID      25:入力日時
136
137 # 更新フラグが8:削除のものは排除
138 gawk '$22!="8"{print $0}'          |139 #------------------------------------------------------------------------------140 # 検索処理
141 #------------------------------------------------------------------------------142 # 店舗コードによる絞込み
143 if [ ${tenpocd} != "_" ] ; then
if 文を活用して、
店舗コードの絞り込み指定があった場合のみ、144   gawk '$1=="'${tenpocd}'"{print $0}'
gawk で絞り込む。( そうでない場合は cat)
145 else
146   cat if 文を丸ごとパイプで繋ぐことで、
147 fi |gawk が選択された場合も
148
cat が選択された場合も次のコマンドへ
149 # 担当者に条件があれば検索パイプされる。
150 if [ ${tantouid} != "_" ] ; then

7

USPMAG 201312.indb

7

2013/12/27

14:26:08

1. 朝のシェルスクリプトコードレビュー会
151   gawk '$20=="'${tantouid}'"{print $0}'
152 else
153   cat 154 fi |155
156 # 取込チェック結果に条件があれば検索
157 if [ ${torikomi_kubun} != "_" ] ; then158   gawk '$15=="'${torikomi_kubun}'"{print $0}'
159 else160   cat 161 fi |162
163 # エラーフラグ(表示フラグ)に条件があれば検索
164 if [ ${hyouji_data} != "_" ] ; then165   gawk '$17=="'${hyouji_data}'"{print $0}'
166 else167   cat 168 fi  > ${tmp}-search_result
169
170 # 該当データが無い場合、検索結果0件として終了
171 [ ! -s ${tmp}-search_result ] && ZERO_HIT_EXIT
172                       :全部載せきれないため、一部を抜粋しました。興味と AWK のパターン部分に条件をまとめて記述するこ深かったのは if 文を丸ごとパイプで繋いでいる部分とでしょう。けれども、見た目がゴチャゴチャするし、です。絞り込みに使いたい項目が 4 つありますが、そ絞り込む必要が無いと始めからわかっている場合は、れら全てが毎回必要なわけではありません。必要な場

cat を経由させる方が明らかに速いのです。

合だけ AWK で絞り込み、そうでない場合は cat でそ

これは、真似したい小技だと思いました。こういうのまま次へ送る、というコードを、if 文を丸ごとパイ

自分に無い発想に出会えるところもまた、コードレ

プで挿むことで実現しています。これはウマい！

ビュー会のいいところです。

こういう書き方をするという発想がなければ、きっ[2] tag*コマンド(*3)を活用した伝票処理プログラム
二人目は、若手の技術研究員見習い (?) の村本さん
による発表です。

というものだったそうです。
村本さんにとってはトレーニング課題になっていた

村本さんは、ユニケージの仕事に携わってまだ２かものの、ユニケージ開発手法に慣れているエンジニア

月程だそうで、そんな村本さんにはユニケージ開発手達にとっても、tag* コマンドは比較的新しい要素と法のトレーニングを兼ね、新しく開発された tag* コ
マンドの評価をするための伝票処理プログラム制作を任されたとのこと。今日のレビューにて、それが適切*3 tag* コマンドとは
AWK や sort、それに従来の各種 Tukubai コマンドでなコードであるかどうか、様々な意見が出てきました。

は、加工対象フィールド指定にフィールド番号を用い■■概要と番号の付け直しが生じるという不便がある。

このプログラムは伝票を処理するためのもので、COBOL が得意とする処理がユニケージでできる例だ
そうです。これをビジネス版 Tukubai で用意されているコマンド、とりわけ tag* コマンドを用いてシェ
ルスクリプトに移植し、性能や使い勝手を評価しよう

8ていた。しかしこの場合、フィールドの並びが変わる
そこで SQL 同様、名称での指定ができるよう、AWK
等の UNIX 標準コマンドを含め、従来のコマンドをラッピングしたコマンド群のこと。
※ tag* コマンドは、前号特集でも紹介した AWS Tukubai
によって気軽に体験することができる。

USP MAGAZINE 2014 winter

USPMAG 201312.indb

8

2013/12/27

14:26:08

特集― 突撃！隣のコードレビュー会 ～ あなたのコード見せてください
いえます。
AWK や sort、それに従来の各種 Tukubai コマンド
では、加工対象フィールド指定にフィールド番号を用います。しかしこの場合、フィールドの並びが変わると番号の付け直しが生じるという不便があるのです。
そ こ で SQL 同 様、 名 称 で の 指 定 が で き る よ う、
AWK 等の UNIX 標準コマンドを含め、従来のコマン

ドをラッピングしたコマンド群が tag* コマンドです。
（tag* コマンドは、前号特集で紹介した AWS Tukubai
によって気軽に体験することができます）
このコードは、この tag* コマンドを本格的に活用してみたコードになっているというわけです。
初心者ゆえのツッコミ以外にも、tag シリーズコマ
ンドの使用上の注意に関する議論が起こりました。

リスト 3. tag* コマンドを活用した、COBOL 処理ライクな伝票処理シェルスクリプト（一部抜粋）
43                       :44 # 2-2 当日売上データファイルの伝票区分に上記が存在する場合
45 # 2-2-1当日売上データファイル.売掛先コードが売掛先マスターに存在しない場合（３を参照）
46 #   入力データをそのまま当日売上エラーデータに出力する。
47 tagmsort key=売掛先コード $tmp-ok                                     |48 tagself 売掛先コード 現法コード 作業日/予備2                          |49 tagcpy 売掛先コード+現法コード TAGKEY                                 > $tmp-meisai
50 tagself 売掛先コード 現法コード IOCS 予備1/予備2 $datd/URIKAKE-MASTER |51 tagcpy 売掛先コード+現法コード TAGKEY                                 |52 tagmsort key=売掛先コード                                             |53 tagjoin0 +ng key=売掛先コード - $tmp-meisai                           > $tmp-uri-toujitu 2> $outd/TOUJITU-URI-ERROR
awk よりも join0 の方が速いので、
54
ここは tagjoin0 でレコード抽出すべき55 # 2-2-2 当日売上データファイル.売掛先コードが売掛先マスター存在する場合（３を参照）
56 #   2-2-2-1 当日検収明細データの明細レコードを編集して出力する。
57 #   2-2-2-2 当日検収明細データの現法コードが("CHN","KOR","TIW")以外の場合
58 tagawk 'NR==1; NR>1&&%{現法コード}!~/^(CHN|KOR|TIW)$/{print}' $tmp-uri-toujitu      > $tmp-noasia
59 tagmsort key=伝票区分 $datd/301VOUCHER-DIV-1                                        > $tmp-301VOUCHER-DI
V-1
なぜマスターデータをいちいちソート？
ソート済のものを置いておけばよいと思う
60 tagmsort key=伝票区分 $tmp-noasia                                                   |61 tagjoin1 +ng key=伝票区分 $tmp-301VOUCHER-DIV-1 -                                   > $tmp-mok 2> $tmp-m
ng
実際のレコード抽出はマスターデータファ
イルに書かれている情報を見て判断してい62るのだから、コメントに即値を書くべきで
63 # 伝票区分(VOUCHER-DIV)が("118","119","128","129", はないのではないか
64 #                         "130","135","140","145",
65 #                         "150","155","157","198","199")の場合
66 tagawk 'NR==1;                                                          \67         NR>1{                                                           \68           if(%{消費税記載区分}==2){                                     \69               %{税額}=%{税額}*-1;                                       \70               %{商品コード}="TAX";                                      \71               %{税抜き金額}=0;                                          \72           print}}' $tmp-mok                                             > $tmp-OK
73 #tail -n +2                                                             > $tmp-OK
74 # 伝票区分(VOUCHER-DIV)が("110","113","114","120",
75 #                         "125","138","149","148",
76 #                         "149","158","159","190","193","194")の場合
77 tagawk 'NR==1;                                                          \78         NR>1{                                                           \フィールド指定で "A/B"（フィールド A か79           if(%{消費税記載区分}=="2"){                                   \らフィールド B）と記述したら、フィール
80               %{税額}=%{税額}*+1;                                       \ドの並び順が変わった時に出力が変わってしまう。これではフィールドを番号指定し81               %{商品コード}="TAX";                                      \た時のデメリットをひきずってしまう
82               %{税抜き金額}=0;                                          \↑でも、フィールド数が何十個もある場合、83           print}}' $tmp-mng                                             |いちいち何十個も書いていては大変だし、
84 cat - $tmp-OK                                                           |読みづらいと思う
85 tagself TAGKEY 売掛先コード/予備2                                       |↑ RDB でもそうだけど結局、データ構造の86 tagdelf TAGKEY                                                          |設計をうまくやることが大事だということ

9

USPMAG 201312.indb

9

2013/12/27

14:26:08

1. 朝のシェルスクリプトコードレビュー会
87 tagself 現法コード 売掛先コード 作業日/予備2                            |88 tagmsort key=現法コード@売掛先コード                                    > $tmp-TOUJITU-KENSHU-MEISAI
89
90 # 当日検収明細の編集処理
91 tagchange 税抜き売単価 売単価 $tmp-TOUJITU-KENSHU-MEISAI |92 tagchange 売単価通貨コード 通貨コード                    |93 tagchange 明細税込み金額 税込み金額                      |94 tagchange "注文番号(親)(明細)（20+54）" '注文番号(親)'   > $outd/TOUJITU-KENSHU-MEISAI95                       :

■■質疑はこう書けばいいのかなぁ」って雰囲気が掴めてきたんじゃないかなぁと。

レビューア：このプログラムは全部で何行ですか？

レビューア：ところで、これまでプログラムの経験っ

レビューア：作るのにどれくらいかかりましたか？

村本さん：いえ、全く初めてです。

村本さん：コメント・空行を除いて、実質 174 行です。
村本さん：２週間ちょっとですね。まともに書いたのはこれが初めてだったので。

てありましたか。

◇◇◇

いくつかツッコミは受けていましたが「全く初めて」レビューア：だいぶ日数かかりましたね。でもその後でもここまで書けちゃうものなんですね。自分が全くはどうですか？

初めての時に書いたプログラムは一体どんな出来栄え

村本さん：この次に書いたプログラムは同じくらいでだったかな？

したが 3 日間くらいで書けました。取り扱うデータ書いていたような気がします。ここまで書けるのもユが少ないというのもありましたが、でも「こういう時ニケージが説く作法によるのでしょうか……。

と想像すると結構へんてこなコードを[ 番外 ] シェルスクリプト製ショッピングカート
三人目は……なぜかレポーターの私（の中の人＝松浦）のコードレビュー。取材する側のはずなのですが、「じゃあ、今度はヨメスケさんお願いします」ということで、逆にこちらが突撃レビューされることに。

せるなど、凝った作りにしてるのですが……。

■■案の定、多数のツッコミがまず「ユニケージの作法からすると、全体的にシェ

確かに私個人もシェルスクリプト好きで、前号の編

ル変数を使い過ぎ」ということです。理由は、変数の集後記では「シェルスクリプト製ショッピングカート

代入をあちこちで行うと「この時点での値は何だっを作るぞ！」などと、豪語しとりました。これまでのけ？」と上の行のコードを読み返させてしまうため取材でユニケージの作法は結構見聞きしていたものに、目線の移動を招くことになり、結果として読み難の、実際のユニケージエンジニア達からすると一体どいコードになるからだそうです。

れだけのツッコミどころを秘めているのでしょうか。
ご覧ください。（・_・;）■■概要
リスト 4 は、ショッピングカートには付きものの「カ

確かに、前のお二人のコードを見ると、冒頭で値を定義して、あとはほとんど参照するだけですね。それに、シェル変数の多用は良くないと説く記事「ユニケー
ジエンジニアの作法 その四」を、過去に自ら編集しておりました……。

ゴに入れる」ボタン押下時に走る Ajax 処理を抜粋しまた、外部データである環境変数をコマンドの引数たものです。Cookie で買い物カゴ ( セッション )ID をとして利用する記述 (285 行 ) も、セキュリティーホー

管理しており、カゴ入れボタンが押されたらサーバー

ルの元になりやすいのでやらないとのこと。こういうで保持しているセッションファイルを更新し、応答を時は、内部結合用のコマンド join0 を使い、マスター返します。複数サイト間でカゴを共有できるようにと、ファイルに記述してあるいずれかの行と一致するかを

Cross-Origin Resource Sharing という規約にも対応さ見て判定するんだそうです。……なるほど。

10 USP MAGAZINE 2014 winter

USPMAG 201312.indb

10

2013/12/27

14:26:09

特集― 突撃！隣のコードレビュー会 ～ あなたのコード見せてください
リスト 4.「カゴに入れる」ボタンが押された時に呼び出される Ajax（一部抜粋）
239                       :変数に値を書き込んでいる箇所が240 # === (これより breakdown 区間) =======================================
全 体 的 に 多 い。（ 今 の 値 は 何 だ っ241 failure=0
け？と、読む人の目線移動を招き、可読性を下げる要因になる）
242 while [ 1 ]; do
243
244 # --- 取引対象商品在庫数は足りているかどうか確認 --------------------245 GET_STOCKQTYS.SH $reqpid > $Tmp-currentstock
246 [ $? -eq 0 ] || errorcode_exit 'Cannot_check_stock_quantity'
247 curqty=$(cat $Tmp-currentstock | self 2)
248 if [ \( $curqty != '*' \) -a \( $curqty -lt $reqqty \) ]; then249   failure=1
自作のシェルスクリプトを呼びだす時は、必ずフルパスで指定すること。環境変数 PATH を不正に書き250   break
変えられていたら、何が呼び出されるかわからない。
251 fi252
253 # --- セッションファイルの中身を更新する ----------------------------254 zgrep -v "^$reqpid[[:blank:]]" "$File_session" >  $Tmp-newsessionfile
255 echo "$reqpid $reqqty"                         |256 awk '$2>0'                                     >> $Tmp-newsessionfile
257 cat $Tmp-newsessionfile |258 gzip                    > "$File_session"
259 [ $? -eq 0 ] || errorcode_exit 'Failed_to_update_the_session_file'260
261 break; done
262 # === (breakdown 区間ここまで)========================================
263
264 # --- Cookieの寿命分だけ延長した日時を得る(dummy sessionでない場合) -265 cookiestr=''
HTTP のセッション管理を行うための Cookie。
266 if [ "_$visitorid" != '_.' ]; then
ここでは expire を 24 時間後にセットするた
267   newexpire=$(TZ=UTC/0 date +%Y%m%d%H%M%S                 | めのタイムスタンプを生成している。
268               calclock 1 -                                |269               self 2                                      |270               awk '{print $1+60*'$COOKIE_LIFELIMIT_MIN'}' |271               calclock -r 1 -                             |272               self 2                                      )273   case "${HTTPS:-off}" in [Oo][Nn]) secure='; secure';; *) secure='';; esac
274   cookiestr=$(printf '\nSet-Cookie: visitorid=%s; expires=%s; path=/%s' "$visitorid" "$(cookiedate $new
expire)" "$secure")
275 fi276
277 # --- Cross-Origin Resource Sharing 対応 ----------------------------278 # 環境変数HTTP_ORIGINと等しい文字列の行が ALLOWED_ORIGIN_LIST.TXT の中にあったら279 # CORSに対応した2つのHTTPヘッダーを生成する
280 cors=''
281 cat $Homedir/CONFIG/ALLOWED_ORIGIN_LIST.TXT |282 env - sed 's/^#.*$//'                       | # コメント除去1
283 env - sed 's/[[:blank:]]\{1,\}#.*$//'       | # コメント除去2
284 grep -v '^[[:blank:]]*$'                    | # 空行除去
285 awk '$1=="'"$(echo "_${HTTP_ORIGIN:-.}" | sed '1s/^_//' | tr -d '"')"'"{ret=1} END{exit 1-ret}'
286 if [ $? -eq 0 ]; then287   cors=$(printf '\nAccess-Control-Allow-Origin: %s\nAccess-Control-Allow-Credentials: true' "$HTTP_ORIGIN")
288 fi
環境変数をコマンド引数にすることは、一歩間違うとセキュリティー
ホールに繋がるのでやるべきではない。
289
この行のように AWK で特定のレコードを抽出したいのなら、代わりに290 # --- HTTPヘッダー送信 ----------------------------------------------Tukubai の join0 コマンドを使うべき
291 cat <<-HTML_HEADER
292
Content-Type: text/plain$cookiestr$cors
293
Cache-Control: private, no-store, no-cache, must-revalidate294
Pragma: no-cache295
296 HTML_HEADER
297                       :

11USPMAG 201312.indb

11

2013/12/27

14:26:09

未来に活きる！ 現場で使える！

データモデリング
第1回

データモデリングとモデリング熊野憲辰

企業情報システムに欠くことのできないデータベース。各種 NoSQL が注目されるが、今なお多くの企業システム、特に重要な基幹業務については RDB および RDBMS が支えているのが実情だ。しかし、長年改修を重ねてきたデータ

ベースを基盤とするシステムが経営環境の目まぐるしい変化に追従できなくなっている。その再構築においてまず鍵を握るのは、ビジネスや業務を可視化する「モデリング」である。
熊野と申します。今回から何回かにわたり、「データモデリング」をテーマに記事を連載します。

エンタープライズシステムで噴出する様々な問題

初回ですので、簡単に自己紹介をさ作ったシステムを使っている企業は少なくない。大企業においてとりわけ顕著である。逆に、中小企業のほうがコンシューマ系のサービスアプリなどをせていただきます。1989 年に製薬会

昨今、エンタープライズ系のシステ

軽快に使いこなし、企業を取り巻く環社の情報システム部門に配属され、そムよりも、コンシューマ系のアプリ

境変化や技術の進展に対して俊敏だ。

こで自社情報システムの設計～内製開ケーションやクラウドサービスのほう

20 ～ 30 年 前、 大 企 業 は 大 型 コ ン

発を担当してきました。2013 年 9 月が必要とされる技術の水準も高く、開ピュータを保持し、専用回線を敷き、末に退職し、エンジニアとして独立、発者にとっては花形の仕事だ。それにそれまで人手が主体だった定常的な業現在に至ります。

比べると、エンタープライズ系のシス

務の電算化や省力化を力強く推進しテムは、地味でありすでに語りつくさた。しかし、業務の効率化が一巡してれた感もある。

しまうと古いシステムが現在では足か

また、ユーザー企業の IT 部門を経営
課題の解決に向けた活動に直結させることを目的とした「特定非営利活動法

しかし、それは表層的な見方に過ぎせになり、それを有する大企業ほど目

人システムイニシアティブ協会」で運ない。エンタープライズシステムは今

まぐるしい経営環境に追随できず、鈍営に携わっています。長年本業に IT を日もなお、企業ビジネスに価値を提供

重に映る。

利用してきたバックグラウンド、またするシステムであり続けている。歴史

そこで、情報システムの再構築だ、

ユーザー主体のシステム開発を推進しある会社のシステムは機能拡張を重ねとなるのだが一筋縄ではいかない。理

てきた経歴がありますので、この連載て大規模化、複雑化しているが、その由はいくつもある。システム開発時には、特にユーザー企業の IT 部門の方々システムを開発し、安定的に運用する

書かれたはずの仕様書が見当たらなに是非ご覧頂きたいと考えています。

ことは、極めて高度な知的作業である。

い、業務を理解している IT 部門人員

データモデルを武器として使いこなせ

企業活動は生き物であり、様々な変化が不足している、縦割り組織の弊害なれば、自社のビジネスをより深く理解と制約を内包している。これを支えるどなど。なかでも仕様書はまったくア

でき、強くすることにつながります。

のが企業における情報システムの本来テにならないといえるだろう。マクロ

本連載の第 1 回では、私がユーザーの役割である。だがそれを阻害する多に俯瞰する仕様記述はほとんど存在せ企業の情報システムの設計～開発をくの問題を抱えていることも事実だ。

ず、ミクロなプログラムレベルの仕様行ってきた中で感じた様々な問題の提以下、エンタープライズシステムに示から、始めたいと思います。

おける主たる問題を 2 点示す。

1. 情報システムの老朽化
いまなお 20 ～ 30 年前にシステムを記述はたいてい間違いだらけだ。

2. 意図を汲めないテーブル設計
前述のように、システムの仕様書はどこの企業もかなり脆弱だ。しかし、

22 USP MAGAZINE 2014 winter

USPMAG 201312.indb

22

2013/12/27

14:26:15

未来に活きる！現場で使える！データモデリング
データベースにおけるテーブルの定義書というものは存在する。これが無いとデータベー
スを作る上で話にならない。
テーブルの定義書は、

テーブル定義書
NAME

xxxxx

DATE

xxxxx

サブ NAME

xxxxx

change.D

xxxxx

DB NAMExxxxx

DB xxxxx

xxxxx

ユーザ

xxxxx
xxxxx

一般的にデータベースのテーブル一つ一つの項目レイアウトとして記述されている。
しかし、エンタープ
ライズシステムの再構

xxxxx
xxxxx

フィールド

xxxxx

膨大な項目

xxxxx
xxxxx
xxxxx

・
・
・

xxxxx

・
・
・

築の場面において、このテーブルの項目レイ
アウトを、ためつすがめつ眺めてみて

これらの項目や属性を示すデータ群

すと、私は以前勤めていた会社でシスも、データが持つビジネス上の「意味」

を立体的に表現し、ビジネスまたは業

テム開発時に要件定義書、基本設計書がなかなか見えてこないのだ。別の言

務を可視化するモデル化の作業に欠かなどを書いたことがない。これらはすい方をすると、テーブル設計におけるせない手段の 1 つがデータモデリン

べてモデルに帰着するのである。モデ意図や全体の構造が読み取れない、項グ、ということになる。データモデル

ルはいわば通常のシステム開発で使わ目間の帰属性もあいまいだ。そして、を的確に記述することで、ビジネスをれる「仕様書」そのものである。だか

設計者の真意を探るために項目名、項可視化することができる。

ら、要件定義書、基本設計書という言

目の値、実際のデータを基に、“ 推理 ”

事 実、 多 く の 企 業 に は、 デ ー タによる現状分析が始まることになる。

モ デ ル と し て の 物 理 的 な ER（Entity

人間は言語なくして思考することは

ところが、テーブル項目の数は膨大

Relation）図は（それなりに）存在する。

できない生き物だ。また、モデルは言であり、なおかつ各項目間の関係・制

しかし、上述のようにフラットにたく語の一種である。ゆえに、人がモデル

約にも気を配る必要がある。筆者の経さんの項目を横に並べただけのテーブを記述することは、思考することと等

験上、現在使われてない項目が全項目

ル定義書や物理モデルを眺めただけで価であるといえる。モデルが思考のたの中に 10 ～ 20％ほど混在しているもは、システムに込められた真意を読みめの箱庭装置であるといえば、この意のだが、これがまた厄介だ。

取ることは難しい。

図が伝わるであろうか？

テーブル定義が単なるフラットな項
目一覧になっている事態も頻発している。とりわけ古いシステムになるほど葉がそもそも出てこない。

モデルを描くための記述文法はそれモデルとは？

一つのテーブルが有する項目数が多ほど難しいものではない。実は、それよりもデータモデルと表裏一体となっているビジネスの構造や、業務と役職

く、推理の邪魔をする。こうした多く

そこで、あらためて「モデル」が重の項目を持つテーブルには、実際には要になる。モデルとデータモデルは厳の関係を精確に紐づけるなどするほう

いくつものサブタイプ構造が見つかる

密には異なる。次回以降それを詳述すだからこそ、モデルは、社外の人間ものだ。サブタイプ構造とは、ある区

るが、一言でいうとモデルはビジネスではなく、ビジネスを知っているべき分となる項目で大きくレコードが分割や業務を記述するために描かれる記述

企業の IT 部門の人員が描かなくてはされる構造を指す。

文法の総称である。モデル化の手段はならないと思っている。

が、はるかに難しい。

また、オプション項目も多くのデー

いくつもある。UML でもポンチ絵でタベースで見受けられる。これは必須

もモデルはモデルである。データモデ

次回以降、エンタープライズシステム

入力の項目でなく、必要に応じて記録

ルもモデルの 1 つだ。ただ、RDB ののモデリングについて、詳細に解説をしされる属性のことである。

設計など少し実装寄りになる。思い返ていきます。よろしくお願いします。

23

USPMAG 201312.indb

23

2013/12/27

14:26:16

body (2013-12-09 20:37)

TEX ͷ‫ڧ‬Έ͸ϓϩάϥϜʹ͋Γ̩̪̜̎̌̍̏Ϩϙʔτ
USP MAGAZINE ฤू෦օ͞Μ͸ TEX*1 ͱ‫ݺ‬͹ΕΔιϑτ΢ΣΞΛ͝ଘ஌Ͱ͠ΐ͏͔ɻςΩετΤσΟλʔͰϚΫϩΛ‫ه‬ड़͢Ε͹ɺͦΕ͚ͩͰ૊൛*2 ࡞‫ࡁͰ·ۀ‬ΜͩจॻΛੜ੒ͯ͘͠ΕΔιϑτ΢ΣΞͷ͜ͱͰ͢ɻHTML ͕͜ΕʹۙΜɺ‫ࢉܭ‬υϦϧͳͲͷ໰୊ͱղ౴ΛϓϩάϥϜͱ࿈‫ܞ‬ͯࣗ͠ಈੜ੒͍ͯ͠Δͱ঺հ͞Ε·ͨ͠ɻͦΜͳ਺ʑͷൃදͷதͰɺಛʹੌ͍ͱ‫ൃͨ͡ײ‬දΛ

2 ͭ঺հ͠·͢ɻ͍ଘࡏͱ‫͑ݴ‬ΔͰ͠ΐ͏ɻҧ͍͸ HTML ͕ Web จॻ࡞੒Λಘҙͱ͍ͯ͠Δͷʹର͠ɺTEX ͸਺ࣜΛѻ͏࿦จ࡞੒ʹಛʹ޲͍͍ͯΔͱ͍͏఺ʹ͋Γ·͢ɻ೔ຊॳ։࠵ͷ TEX ࠃࡍϛʔςΟϯά

1.1 How I use LATEX to make a product catalogue that doesn’t look like a dissertationʮ‫ͨݟ‬໨͕࿦จष͘ͳ͍੡඼Χλϩάͷ࡞Γํʯͱ୊ͨ͜͠ͷൃද (ൃදऀ Jason Lewis ࢯ) ʹ͸‫͔͞ڻ‬‫ڈ‬Δ 10 ݄ 23 ೔ʙ26 ೔ͷ 4 ೔ؒɺ౦‫ژ‬େֶۨ৔Ε·ͨ͠ɻൃද͕࢝·Δͱ‫؍‬ཡऀʹαϓϦϝϯτͷΧ

Ωϟϯύεʹͯɺୈ 34 ճ TEX Users Group ೥࣍େλϩά࡭ࢠ͕ճཡ͞Ε͖ͯͨͷͰ͕͢ (ࣸਅ 1)ɺԿͱ

ձ (TEX ϢʔβʔʹΑΔࠃࡍձٞ) ͕։࠵͞Ε·ͨ͠ɻ͜Ε͸ LATEX Ͱ࡞ͬͨͱ͍͏ͷͰ͢ɻʮTEX Ͱ͜͜·೥ʹҰճɺ͜Ε·Ͱ 34 ճ΋։࠵͞Ε͖ͯ·͕ͨ͠ɺ࣮

ͰͰ͖Δͷ͔ʂʯͱɺͨͩͨͩ‫ͨ͠·͖ڻ‬ɻ͸೔ຊͰ͸͜Ε͕ॳΊͯͷ։࠵ͩͬͨͷͰ͢ɻ

TEX ͱ͍͑͹࿦จ࡞੒Ͱ࢖ͬͨͱ͍͏ํ͕ଟ͍ͷͰ͸ͳ͍Ͱ͠ΐ͏͔ɻͪͳΈʹ USP ‫ڭ‬ҭߨ࠲ͷςΩετ࡞੒΋͜ͷιϑτ΢ΣΞͷ͓ੈ࿩ʹͳ͍ͬͯΔͦ͏
Ͱ͢ɻ͔͠͠ TEX ͷ‫ڧ‬Έɺ͋͑ͯ TEX Λબ୒͢Δҙٛ͸Ͳͷ͋ͨΓʹ͋ΔͷͰ͠ΐ͏͔ɻ͜ΕΛ஌Δ΂͘

TEX ͷ࠷৽ٕज़ɾ‫ྫࣄ༻׆‬ͷ਺ʑ͕൸࿐͞ΕΔ͜ͷϛʔςΟϯάʹࢀՃ͖ͯ͠·ͨ͠ɻ1 ൃදʹ͸‫͔͞ڻ‬ΕΔ͹͔Γ։࠵ॳ೔͔Βɺେม໘ന͍ൃද͕໨നԡ͠ɻ‫͍ͯ؍‬ͯಛʹ‫ͱͨ͜͡ײ͘ڧ‬͸ɺTEX ͱϓϩάϥϜͱͷ਌࿨ੑͰͨ͠ɻྫ͑͹ɺTEX ͷϚΫϩΛ‫ه‬ड़͢Δʹ͋ͨͬ
ͯ Lisp ͷ੍‫ߏޚ‬จΛ࢖͑ΔΑ͏ʹ͢Δ LISP on TEXͱ͍͏֦ு‫ػ‬ೳͷ঺հ΍ɺTEX ϚΫϩதʹ PythonίʔυΛຒΊࠐΉͱͦͷ࣮ߦ݁Ռ͕υΩϡϝϯτʹͳ
Δͱ͍͏ PythonTEX*3 ͷ঺հͳͲͰ͢ɻ
‫ؔ͢ʹྫࣄ༻׆‬ΔൃදͰ΋ɺ΍͸ΓϓϩάϥϜͱͷ࿈‫ܞ‬Λ͏·͘‫͍ͯ͠༻׆‬Δ΋ͷ͕͋Γ·ͨ͠ɻͦͷҰͭɺֶशक़ͷࣄྫͰ͸ɺक़ੜୡʹղ͔ͤΔӳࠃ਺ཧࣾͷ໰୊Λ࡞ΔͨΊʹ TEX Λར༻͍ͯ͠Δͷ͸΋ͪΖࣸਅ 1

LATEX Ͱ੍࡞͞ΕͨΧλϩά࡭ࢠҰମͲ͏΍ͬͯ࡞ͬͨͷ͔‫ͳʹؾ‬Δͱ͜ΖͰ͕͢ɺίπ͸࣍ͷ 2 ͭͩͦ͏Ͱ͢ɻ

• ϑΥϯτ͸αϯηϦϑ‫( ܥ‬࿨จͰ͍͏ͱΰγοΫ) ΛબͿͱͦΕͬΆ͘ͳΔɻ
• ৭͖ͭͷ௕ํ‫ܗ‬ΛσβΠϯʹੵ‫ۃ‬తʹ‫͢༻׆‬Δ
ͱɺ΍͸ΓͦΕͬΆ͘ͳΔɻ

*1 ςϑ·ͨ͸ςοΫͱಡΈ·͢ɻ*2 ຊจ΍‫ݟ‬ग़͠ɺਤ൛ͷϨΠΞ΢τΛߦ͏͜ͱɻ
*3 ࠷ۙͷ T X Πϯετʔϥʔύοέʔδʹ͸ඪ४Ͱऩ࿥͞Ε͍ͯΔΑ͏Ͱ͢ɻE

67

USPMAG 201312.indb

67

2013/12/27

14:26:55

body (2013-12-09 20:37)

͔֬ʹ഑෍͞ΕͨΧλϩά͸ɺ͜ͷ 2 ͭͷίπΛ
क͍ͬͯΔ͚ͩͳͷʹɺ͔ͳΓ‫ݟ‬ӫ͕͑ྑ͍΋ͷʹͳ͍ͬͯ·͢ɻ
͔͠͠ΧλϩάΛ࡞Γ͍͚ͨͩͳΒ΂ͭʹ TEX Λબ͹ͳͯ͘΋͍͍Α͏ͳ‫͕͢·͕͠ؾ‬ɺLewis ࢯ͸

TEX ΛબΜͩཧ༝Λ͜͏ड़΂·ͨ͠ɻ঎඼ΧλϩάΛੜ੒͢ΔͷʹɺDB ͔ΒࣗಈͰ঎඼σʔλΛҾͬு͖ͬͯͯ؆୯ʹΧλϩάΛ
࡞Δͱ͍͏ٕ͕࢖͑Δͷ͸ɺϓϩάϥϜ΍εΫ
Ϧϓτͱͷ૬ੑ͕ྑ͍ TEX ͳΒͰ͸ͩɻࣸਅ 2͜͜Ͱ΋ TEX ͱϓϩάϥϜͷ਌࿨ੑ͕‫͔͞׆‬Ε͍ͯ·ͨ͠ɻHTML Խ͠Α͏ͱ͍ͯ͠Δ PDFɺ࣮͸ʜʜ

HTML5 Λ‫͢࢖ۦ‬Δͱ͜͜·ͰͰ͖ͯ͠·͏Μͩͦ͏Ͱ͢ɻத਎ͷιʔείʔυ͕ҰମͲ͏ͳ͍ͬͯΔͷ

1.2 Online Publishing via pdf2htmlEX͔େม‫ڵ‬ຯ͋Γ·͕͢ɺͳΜͱ͜ͷιϑτɺΦʔϓϯιʔεͰެ։͞Ε͍ͯͯ୭Ͱ΋ࢼͤΔͱͷ͜ͱɻεΰʮpdf2htmlEX ʹ Α Δ Φ ϯ ϥ Π ϯ จ ॻ ࡞ ੒ ʯͱ͍Ͱ͢ɻੋඇօ͞Μʹ΋ࢼͯ͠΋Β͍͍ͨͰ͢ɻ୊ ͠ ͨ ൃ ද (ൃ ද ऀ Lu Wang ࢯ) ʹ ΋ ‫͠ · ͖ ڻ‬ͨɻpdf2htmlEX*4 ͱ͸ɺ໊લͷͱ͓Γ PDF จॻΛHTML ʹม‫͢׵‬ΔίϯόʔλʔͰ͢ɻ͔ͦ͠͠ͷ࠶

2 ࠓ΋Ѫ͞Εଓ͚͍ͯΔ TEX‫ݱ‬ੑ͕൒୺͡Όͳ͍ͷͰ͢!! ͦͷ͓͔͛ͰɺTEX ͔Β

TUG 2013 ͸େม໘ന͍ΠϕϯτͰͨ͠ɻൃද಺༰

ੜ੒ͨ͠ඒ͍͠਺ࣜೖΓͷจॻ΋ɺͦͷඒ͠͞Λอͬ͸ɺࠓճ঺հͨ͠Α͏ͳϓϩάϥϜͱͷ࿈‫ྫࣄܞ‬΍ɺ

ͨ·· HTML ԽͰ͖Δͱ͍͏ͷ͕΢ϦͰ͢ɻจॻ࡞੒‫ۀ‬຿ʹ͓͚Δ‫ྫࣄ༻׆‬ɺ։ൃ্ͷۤ࿑࿩*5 ɺ

Wang ࢯ͸ɺʮ͜͏͍͏ࡶࢽͷυΩϡϝϯτ͕͋Γ·͢ɻ͜ΕΛ html2EX Ͱม‫͢׵‬ΔͱͲ͏ͳΔͰ͠ΐͦͯ͠࠷৽ͷ LATEX3 ͷಈ޲ͳͲɺ੝Γͩ͘͞ΜͰͨ͠ɻ͍ͣΕͷൃදऀ΋օָͦ͠͏ʹ‫ͨ͠·͑ݟ‬ɻ͏ʯͱɺεϥΠυͰαϯϓϧจॻΛ‫ͨ͠·͍ͯͤݟ‬HTML5 ͷొ৔΋͋Γɺ࠷ۙ͸υΩϡϝϯτͱϓϩ(ࣸਅ 2)ɻதຯ͸શ͘΋ͬͯී௨ͷ঎‫Ͱࢽۀ‬ɺʮ͜ΕάϥϜͷ౷߹͕ଅਐ͞Ε͍ͯ·͕͢ɺ΋ͱ΋ͱ૊൛ͱ͸͍͘ΒͳΜͰ΋ແཧͰ͠ΐɻͲ͜·Ͱ࠶‫͖Ͱݱ‬Δͷ͍͏࣠Ͱߴ౓ʹൃୡ͖ͯͨ͠ TEX ͸ɺͦͷ෼໺Ͱ͸͔ʯͱ൒৴൒ٙͰͨ͠ɻͱ͜Ζ͕ Wang ࢯ͕ଓ͚ͯ

ઌߦ͍ͯ͠ΔͷͰ͸ͳ͍Ͱ͠ΐ͏͔ɻ‫͍ޓ‬ͷ༏Εͨ໘͜͏‫ͨͬݴ‬ͷͰ͢ɻʮ࣮͸ࠓ͝ཡ͍͍͍ͨͩͯΔͷ͸ͷӨ‫ڹ‬Λड͚ͳ͕ΒਐԽΛଓ͚ɺจॻ࡞੒‫͕ڥ؀‬ΑΓ

pdf2htmlEX Ͱม‫ ͨ͠׵‬Web ϖʔδͳΜͰ͢ʯͱɻ

ศརͰޮ཰తͰָ͘͠ͳ͍ͬͯ͘ະདྷ͕଴ͪԕ͍͠

ͦͷ͋·Γͷ࠶‫ݱ‬ੑʹ౓୾Λൈ͔Ε·ͨ͠ɻͰ͢ɻΠϕϯτձ৔ͷ༷ࢠ

TUG 2013 ϙελʔ࣮ߦҕһͷ͓ҰਓɺԞଜ੖඙ઌੜ

ձ৔಺ͷ༷ࢠʢ౻ాᚸ࡞ઌੜʹΑΔ “XΥMTEX”ʣ

*4 http://coolwanglu.github.io/pdf2htmlEX/*5 ॎॻ͖‫ޠݴ‬΍ӈ͔Βࠨ΁ॻ͔ΕΔ‫ޠݴ‬౳ɺଟࠃ‫ޠ‬ରԠͷۤ࿑࿩ͳͲ

68 USP MAGAZINE 2014 winter

USPMAG 201312.indb

68

2013/12/27

14:27:04

徹底仕事術！
仕事術！
C U I 徹底仕ΏͿσΑ·ςίΠఱ‫ܔ‬၌ɔȊɐȊɔȊɐȊɔȊɐȊɔȊɐȊɔȊɐȊɔ₻₏₷₏₻ɔȊɐȊɔȊɐȊɔȊɐȊɔȊɐȊɔȊɐȊɔংٛȇȸ̽͂͜଑̩ȹ༎ਬಿȆ͙̥ͭ

ٝ
ల਱֚

₻₏₷₏₻

ΏͿσΑ·ςίΠఱ‫ܔ‬၌

皆様こんにちは。今月もシェルスクリプト大喜利（略です。そもそも JM にも載っていません。逆にシェ

して sh 大喜利）のコーナーがやってまいりました。

ルスクリプトにとって不可欠な awk や sed 等は年の瀬ですなぁ。大晦日には年越し蕎麦ってのが定OK です。JM にもありますし。でも、よっぽど面

番ですが、由来の一つに「他の麺類より切れやすい蕎麦で一年の厄災を断ち切る」というのがあるんですって。そりゃめでたいのかもしれませんけど、このコー

白ければ、Perl とかなきにしもあらず ??
ࡼȂġOpen usp Tukubai(iuuq;00vfd/vtq.mbc/dpn0) も使用 OK ！

但し、使う意義がそれなりに感じらナーの司会やってるアタクシは、「切る」だの「断ちれないと採用はキビシいですよ〜。

切る」だの言われると、どーしてもパイプ (|) を連想

ルールもおさらいしたところで、さあ始めましょう !

しちゃいまして、しかも「切れたらそれバグでしょ」

ུ๔‫ٳ‬ই

なんて考えちまいます。重症ですね。
さて、そんな危険な (?) シェルスクリプト大喜利。
まずは本コーナーのご説明からいきましょう。

ΏͿσΑ·ςίΠఱ‫ܔ‬၌͉͂ΏͿσΑ·ςίΠఱ‫ܔ‬၌අခ͈σȜσ֚Ȃġsh 大喜利はクイズやテストではありませぬ。なのɃ֚࿚࿒ɄĲ ȡ ů Ȫů ͉֨ତ́ঐ೰ȫ ͈ুடତ͈ಎͅంह̳ͥ ȸΒΛ΃Ȝζϋତȹ ͬ஠̀‫ͥ͛ݥ‬ΏͿσΑ·ςίΠͬ੥̞̩̺̯̞̀ȃ

ズッカーマン数とは、元の値 n の各桁の数字を掛けあわせた数が、元の数 n の約数になっている数 nのこと（例 315 は 3 × 1 × 5 の 15 で割り切れる )。
さて、早速投稿見ていきましょう。

で決まった答えというものはないのです。あえてɝ͚̽̾Ȝ̯͈ٜͭ൞

言うなら面白いスクリプトが正解！

2!$"0cjo0ti
3!tfr!2!%2!}hsfq!.w!1!}ybsht!.j!.Q5!cbti!.d!(!\!%)!
fdip!|~!}tfe!.f!#t0])/]*0]2+0h#!.f!#t0]+%0*0#!.f!
#t0_0|~!&!])0#!}cd!*!>!1!^!''!fdip!|~!(

ඵȂġ面白いスクリプトとは、例えばこんなもの。
ͼȂġ人が考えつかない意外性があるυȂġ美しい、芸術的、記述がシンプル、高速、など

おぉ、これはアタクシの好きな蕎麦……、じゃなくΧȂġアイデア・こだわりが光るてパイプでつながれた一行野郎。添付のコメントによΣȂġネタになるバカバカしさ、くだらなさがある

れば、あれこれ考えた挙句に結局このシンプルな形になど。でも最後のは段位強制返還の恐れありよ。:-)

なったようです。因みに xargs の -i オプションが使え२Ȃġス ク リ プ ト 動 作 環 境 は Linux と し、 基 本 的 にLinux JM(iuuq;00mjovykn/tpvsdfgpshf/kq0) に 記

ない環境では代わりに “.J|~” と書けば動きますよ。
初投稿ありがとう！

なるほどね、各桁の掛け算や載されているコマンド及び機能のみ使用可能としるのに sed で 1 文字ずつ分解しながら “*” を付け足します。これは多くの人が楽しめるようにするためてるのか。それを bc コマンドに食わせて掛け算させなのです。（JM にあるので、C シェル系での解答て剰余を確認するという。ウマイね！

も OK ！

̜͂ ŬŴũȂ ŻŴũ ͜ ŐŌ ̱̱̹͘ͅ）অȂġsh 大喜利はシェルスクリプトを披露する場なので、őŦųŭ ͞ œŶţźȂ őźŵũŰů ͉̈́̓ঀ̻̽͝Θι੝౲਎ဓだ。

ɝ̤ਈ‫ؚ͈̯ͭ‬ٜ൞
2!$"0cjo0cbti
3!

69
6
9

69̲73̲shogiri11.indd 69

2013/12/10 18:47:13

4!tfr!2!%2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
5!bxl!(|gps)j>2<j=>mfohui)%2*<j,,*|6!!!!!!!!!!!qsjoug!tvctus)%2-j-2*#!#~
7!!!!!!~|qsjou!%2~(!!!!!!!!!!!!!!!!!!!!!!!!}
8!bxl!(|tflj>%2<
9!!!!!!!gps)jj>3<jj=OG<jj,,*|tflj>tflj+%jj~:!!!!!!~tflj">1|qsjou!%OG-tflj~(!!!!!!!!!!!}
21!bxl!(%2&%3>>1|qsjou!%2~(

さて次は、2 回目のご参加、お酒屋さん。こちらは、
AWK、AWK、AWK、と綺麗に繋がっていますね。えぇ、
添付のコメントによりますと、1 つ目の AWK で元数を各桁に分解、2 つ目の AWK で分解後の各桁の積を求め、3 つめの AWK でズッカーマン数の条件に当てはまるか判定しているそうです。
さすが、教育講座修了生。分かりやすい単位に処理を分解し、綺麗に解いてきたねぇ。しかも速い！

よし、ඵ౲਎ဓ。これで五段だ。

ɝ൳ହ൳ྴ̯͈ٜͭ൞Ȫ༎ಕĻধ࿂͈സࣣ́ഐܽ٨࣐ொව̱̱̹͘ȫ
2!$"!0cjo0cbti
3!O>%24!sn!unq`/+
5!zft!]
6!!!!!}!ifbe!.o%|O~!]
7!!!!!}!hsfq!.o!z!]
8!!!!!}!dvu!.e;!.g2!]
9!!!!!}!hsfq!.w!(1(!]:!!!!!}!uff!?)hsfq!(\248:^3%(!]21!!!!!!!!!!!!!}!hsfq!.w!.f!(\59^23%(!]22!!!!!!!!!!!!!!!!!!!!!!!.f!(\59^:3%(!]23!!!!!!!!!!!!!?}!unq`3/uyu*]
24!!!!!}!uff!?)hsfq!(\3579^5%(!]25!!!!!!!!!!!!!}!hsfq!.w!.f!(\248:^35%(!]26!!!!!!!!!!!!!!!!!!!!!!!.f!(\3579^55%(!]27!!!!!!!!!!!!!!!!!!!!!!!.f!(\248:^75%(!]28!!!!!!!!!!!!!!!!!!!!!!!.f!(\3579^95%(!]29!!!!!!!!!!!!!?}!unq`5/uyu*!]
2:!!!!!}!uff!?)hsfq!(\248:^7%(!]31!!!!!!!!!!!!!}!hsfq!.w!.f!(\59^47%(!]32!!!!!!!!!!!!!!!!!!!!!!!.f!(\59^87%(!]33!!!!!!!!!!!!!?}!unq`7/uyu*!]34!!!!!}!uff!?)hsfq!(\3579^9%(!]35!!!!!!!!!!!!!}!hsfq!.w!.f!(\3579^39%(!]36!!!!!!!!!!!!!!!!!!!!!!!.f!(\248:^59%(!]37!!!!!!!!!!!!!!!!!!!!!!!.f!(\3579^79%(!]38!!!!!!!!!!!!!!!!!!!!!!!.f!(\248:^99%(!]39!!!!!!!!!!!!!?}!unq`9/uyu*!]
3:!!!!!}!uff!?)hsfq!.w!(\3579^(!]41!!!!!!!}!uff!?)hsfq!.w!(6(!?}!unq`pee`opu6/uyu*!]
42!!!!!!!}!uff!?)hsfq!(6%(!]43!!!!!!!!!}!uff!?)hsfq!!!!(86%(!]44!!!!!!!!!!!!!!!!!?}!unq`pee`86/uyu!!!*!]
45!!!!!!!!!}!uff!?)hsfq!.w!(86%(!]46!!!!!!!!!!!!!!!!!}!hsfq!.w!(6\2468:^+6%(!]47!!!!!!!!!!!!!!!!!?}!unq`pee`opu86/uyu*!]
48!!!!!!!!!?!0efw0ovmm!]
49!!!!!!!*!]
4:!!!!!!!?!0efw0ovmm!]
51!!!!!*!]
52!!!!!?!0efw0ovmm
53!qjoh!.d!3!.j!/3!mpdbmiptu!?!0efw0ovmm

54!tpsu!.on!=)|!fdip!3<!fdip!5<!fdip!7<!fdip!9<!~*!
unq`3/uyu!unq`5/uyu!unq`7/uyu!unq`9/uyu!unq`pee`
opu6/uyu!unq`pee`86/uyu!unq`pee`opu86/uyu!?}!unq
`/uyu
55!
56!qbtuf!.e(!(!]
57!!!!!unq`/uyu!]
58!!!!!=)qbtuf!.e(!(!]
59!!!!!!!unq`/uyu!]
5:!!!!!!!=)dbu!unq`/uyu!]
61!!!!!!!!!}!tfe!(t020!20h(!]
62!!!!!!!!!}!tfe!(t030!30h(!]
63!!!!!!!!!}!tfe!(t040!40h(!]
64!!!!!!!!!}!tfe!(t050!50h(!]
65!!!!!!!!!}!tfe!(t060!60h(!]
66!!!!!!!!!}!tfe!(t070!70h(!]
67!!!!!!!!!}!tfe!(t080!80h(!]
68!!!!!!!!!}!tfe!(t090!90h(!]
69!!!!!!!!!}!tfe!(t0:0!:0h(!]
6:!!!!!!!!!}!nbxl!(|q>%2<!gps)j>3<j=>OG<j,,*!!!!!!!!!!!!!!!!|q+>%j~<!qsjou!q~(!]71!!!!!!!*!]
72!!!!!}!nbxl!(|qsjou!%2&%3~(!]73!!!!!*!]
74!!!!!}!hsfq!(!1%(!]75!!!!!}!nbxl!(|qsjou!%2~(

お名前は「同姓同名」で正しいそうです。同姓同名さんは素朴版、高速版と 2 つ投稿してくれたのですが、高速版を採用。Linux JM に載っていない mawk があり
ますが、堅いことは抜き！ 引数が 100000 くらい以上なら他解答に比べて圧倒的な早さで解き終えます。
ん、42 行目の ping って何だい？

と思ったら投稿

コメントに、テンポラリーファイルが確実に出来るようにするための時間稼ぎなのかい。うーん、zsh とかならここは wait を使ってスマートに行くんだけど、
bash じゃ効かないんだよね、これが。引数が小さいと早さを発揮できないのは一つにはこのせいかもしれないね。今回の最高速解答かつ、2 つのバージョンを送ってくれた努力を称えてඵ౲਎ဓだ！
さて……、2 年半やってきたこのシェルスクリプト大喜利のコーナーなんですけど。ついにこの時が訪れましたよ。何がって？ それじゃ次の投稿いきましょう。

ɝŌ ̯͈ٜͭ൞
2!$"0cjo0ti
3!tfr!2!%2!}
4!xijmf!sfbe!j<!ep
5!!!q>%))!%)fdip!%j!}!tfe!.f!(t0])\1.:^]*0]2+0h(!.f!
(t0%020(*!**
6!!!\!%q!.of!1!^!''!\!%))%j!0!%q!+!%q!**!.fr!%j!^!
''!fdip!%j7!epof

常連の K さん、やはり今回も投稿してきましたね。
内容は、1 から順にズッカーマン数の条件を満たしているか検証するというオーソドックスなもの。ただ、変数 p が i の約数かどうかを判定するのに i を p で割っ

MAGA INE 2014
MAGAZIN014
4 winterwin er70 USP MAGAZINE

69̲73̲shogiri11.indd 70

2013/12/10 18:47:15

徹底仕事術！
仕事術！
C U I 徹底仕ΏͿσΑ·ςίΠఱ‫ܔ‬၌
て p で掛けて i に戻るかを見てるあたりは、ちょっとした工夫ですね。
さあ、採用してしまったぞ。というわけで、֚౲਎ဓ。これで十段。ついに出たー！十段到達おめでとう !!

਱౲ൢోġ̤̠̮̰̞̳͛́͂͘Ȋ
そうそう、ຊ୳ͅ଄̩̱ඳ̞̻̲̠̻ͭͭ͟͝ΈΛΒをプレゼントしなきゃねぇ。考えときます )__< それから、十段獲得者は「師範」の称号を進呈して、また初段からはじまるものということに、ࣽࠨ̱̹͛͘ȃ こ
れからも投稿よろしくお願いしまーす。
◇◇◇「師範」の特典だからというわけでもないんですが、K さんが更に前回のお題に対する改良版を送ってくれたので紹介します。そのお題とはこれです。
ల਱ٝɃඵ࿚࿒Ʉ

⁬଎͈̠̈́͢ Ĵ ࣐ Ĵ Ⴅ⁪ȪႥ‫͉ۼ‬฼‫ڙ‬ΑβȜΆߊ୨̞ͣͦ̀ͥȫ ͈⁫Ĵ ͈̾έ͹ͼσ̦̜ͤ

hoge.3hoge.2hoge.1̳͘ȃ Ⴅ༷࢜ͬ Ź ৊Ȃ ࣐༷࢜ͬ ź ৊Ȃ έ͹ͼσ‫༷ͬ࢜ۼ‬Ż ৊̱͂Ȃ ŹĮŻ ໹࿂́ ĺıɋȂ ĲĹıɋȂ ĳĸıɋٝഢ̵̯ͣͦ
ͥΏͿσΑ·ςίΠ̷̸ͬͦͦ੥̞̩̺̯̞̀ȃĺıɋٝഢࢃ͈ ũŰŨŦįĲ ͉ Ĳ ࣐࿒̥ͣਜ਼ͅ ȨŢġłġĲȩȂ ȨťġŅġĵȩȂ ȨŨġňġĸȩ ͂̈́ͦ͊ୃٜ̱̳͂͘ȃ

元のお題では、回転方向は x-z 平面のみ、かつ対象
データサイズは 3*3*3 限定でよかったのですが、前回
既に回転方法を一般化した解答を送ってきてました。
そして今回、サイズまで一般化できたということで記念に掲載！（編注：掲載の都合で適宜改行してます）
2!$"0cjo0ti
3!$4espubuf/ti!=joqvu`gjmf`obnf?!=pvuqvu`gjmf`obnf?!]
4!$!!!!!!!!!!!!=spubujpo?!=qbe?
5!
6!$hfu![<!uif!nbyjnvn!ovncfs!pg!%2(t!tvggjy
7![>%)mt!%2/\1.:^+!}!tfe!.f!#t0%2]/00#!}!tpsu!.os!}!
ifbe!.o!2*
8!
9!$!hfu!Y-!Z<!uif!nbyjnvn!ovncfs!pg!y-!z!tj{f:!Y>1
21!Z>1
22!gps!j!jo!%)tfr!2!%[*<!ep
23!!!\!.g!%2/%j!^!''!]
24!!!YZ2>%)bxl!(CFHJO|Y>1~
25!!!!!!!!!!|jg!)Y=OG*!|Y>OG~~
26!!!!!!!!!!FOE|qsjou!Y-!OS~(!=!%2/%j!*27!!!Y2>%|YZ2&!+~28!!!Z2>%|YZ2$+!~29!!!\!%Y!.mu!%Y2!^!''!Y>%Y2
2:!!!\!%Z!.mu!%Z2!^!''!Z>%Z2
31!epof

32!
33!qbe>%|5;.A~
34!
35!unq`gjmft`obnf>##
36!ovmm`gjmft`obnf>##
37!gps!j!jo!%)tfr!2!%[*<!ep
38!!\!"!.g!%2/%j!^!!''!|!upvdi!%2/%j<!ovmm`gjmft`obnf>#%2/%j!%ovmm`gjmft`obnf#<!~
39!!bxl!.w!Y>%Y!.w!Z>%Z!.w!Q>#%qbe#!(3:!!!|!qsjoug)#&t!#-!%1*<41!!!!gps)y>OG,2<!y=>Y<!y,,*!|qsjoug)#&t!#-!Q*<~42!!!!qsjoug)#]o#*<~43!!!FOE|
44!!!!jg!)OS!=!Z*!|45!!!!!gps)z>OS,2<!z=>Z<!z,,*!|
46!!!!!!gps)y>2<!y=>Y<!y,,*!|qsjoug)#&t!#-!Q*<~47!!!!!!!qsjoug)#]o#*<~~~(!%2/%j!?!%%/%j48!!unq`gjmft`obnf>#%%/%j!%unq`gjmft`obnf#
49!epof4:!
51!dbtf!%4!jo
52!!#y{291#}#{y291#}#z{291#}#{z291#}#yz291#}#zy291#*!
OY>%Y<!OZ>%Z<<
53!!#y{:1#!}#{y381#}#y{381#}#{y:1#*!OY>%[<!OZ>%Z<<
54!!#z{:1#!}#{z381#}#z{381#}#{z:1#*!OY>%Y<!OZ>%[<<
55!!#yz:1#!}#zy381#}#zy381#}#zy:1#*!OY>%Z<!OZ>%Y<<
56!ftbd
57!
58!gvodujpo!spubuf)*!|59!$spubuf!=joqvu`gjmf`obnf?!=pvuqvu`gjmf`obnf?!]
5:!$!!!!!!!=spubujpo?!=Y?!=Z?!=[?!=OY?!=OZ?
61!!gps!{!jo!%)tfr!2!%7*<!ep
62!!!bxl!.w!{>%{!(|gps!)y>2<!y=>OG<!y,,*!qsjou!y-!OS-!
{-!%y~(!%2/%{
63!!epof!}
64!!dbtf!%4!jo65!!!#y{:1#!}#{y381#*!tpsu!.l2o-2!!.l3o-3!!.l4os-4<<
66!!!#y{291#}#{y291#*!tpsu!.l4os-4!.l3o-3!!.l2os-2<<
67!!!#y{381#}#{y:1#!*!tpsu!.l2os-2!.l3o-3!!.l4o-4!<<
68!!!#z{:1#!}#{z381#*!tpsu!.l3o-3!!.l4os-4!.l2o-2!<<
69!!!#z{291#}#{z291#*!tpsu!.l4os-4!.l3os-3!.l2o-2!<<
6:!!!#z{381#}#{z:1#!*!tpsu!.l3os-3!.l4o-4!!.l2o-2!<<
71!!!#yz:1#!}#zy381#*!tpsu!.l4o-4!!.l2o-2!!.l3os-3<<
72!!!#yz291#}#zy291#*!tpsu!.l4o-4!!.l3os-3!.l2os-2<<
73!!!#yz381#}#zy:1#!*!tpsu!.l4o-4!!.l2os-2!.l3o-3!<<
74!!ftbd!}
75!!bxl!.w!Y>%8!.w!Z>%9!.w!pvu`gjmf`obnf>#%3#!(
76!!!CFHJO|{>2<!pvu>pvu`gjmf`obnf#/#{~
77!!!|!jg)OS&Y">1*!|qsjoug)#&t!#-!%5*!?!pvu~78!!!!!fmtf!|qsjoug)#&t]o#-!%5*!?!pvu~79!!!!!jg)OS&)Y+Z*>>1*!|{,,<pvu>pvu`gjmf`obnf#/#{~~(
7:!~
81!
82!spubuf!%%!%3!%4!%Y!%Z!%[!%OY!%OZ
83!
84!sn!%unq`gjmft`obnf
85!sn!%ovmm`gjmft`obnf

これで三次元なテキストデータも問題無く扱えるよ
うになりますな。記念に੝౲਎ဓしますよ。師範としての二週目も投稿お待ちしてます！さて、二問目！
Ƀඵ࿚࿒Ʉဓ̢̹ͣͦΞ΅ΑΠέ͹ͼσͬΓϋΗςϋΈ Ȫಎ؇‫̵ܙ‬ȫ ̳ͥ
ΏͿσΑ·ςίΠͬ੥̞̩̺̯̞̀ȃ

左寄せなら “tfe! (t0_! +00(” でいけるし、右寄せもrev コマンドの活用でできます。ではセンタリングはどうやる？ということで出題したんですが。さてどう解きますか？

71
7
1

69̲73̲shogiri11.indd 71

2013/12/10 18:47:16

ɝ͚̽̾Ȝ̯͈ٜͭ൞
2!$"0cjo0ti
3!
4!jg!\!.q!0efw0tuejo!^<!uifo
5!!!JoUfyu>#%)dbu!0efw0tuejo*#
6!fmtf
7!!!fyju!2
8!gj
9!
:!NbyMfohui>%)!fdip!#%JoUfyu#!}xijmf!sfbe!MJOF<!ep!
)fdip!#%MJOF#!}hsfq!.p!/!}tpsu!}us!.e!#]o#<!fdip*!}gpme!.x!3!}xd!.m<!epof!}tpsu!.o!}ubjm!.2!*
21!
22!fdip!#%JoUfyu#!}xijmf!sfbe!MJOF<
23!ep
24!
25!!!!$$!ߗ࣐͉ΓϋΗςϋΈ̱̞̈́
26!!!jg!\!.{!#%MJOF#!^<!uifo27!!!!!fdip!##
28!!!!!dpoujovf
29!!!gj
2:!
31!!!MjofMfohui>%)fdip!%MJOF!}!)!hsfq!.p!/!}tpsu!}us!.e!#]o#<!fdip!*!}gpme!.x!3!}xd!.m!*32!!!fdip!.o!#%MjofMfohui;#33!!!tfr!2!%)!fyqs!%NbyMfohui!.!%MjofMfohui!*!}ybsh
t!.j!fdip!.o!#!#34!!!fdip!#%MJOF#
35!
36!epof%0!!0(
5!sn!0unq0nbo%%

うわー、これはやられた !!! man コマンドを使うのか。
うーん、
グルー言語の美学。
スバラシイ！२౲਎ဓ。
ん？まさか、
gori.sh さんも十段到達か。オメデトー !

਱౲ൢోġ̤̠̮̰̞̳͛́͂͘Ȋ
それじゃ、次回から師範で二周目ってことで。よろしくおねがいします。では、最後のお題にいきます。
Ƀల२࿚Ʉً‫ͅݲ‬Οͻτ·ΠςȜߡ̩ͤ̽̀͘΂΃Ώ̈́൲ैͬည
̠ൎࣂ̦̜̱̹ͤ͘ȃ ̷ͭ̈́͏̠ͅΰϋ̭̱̈́͂̀ೇ
࡛ય̭̱̩̺̯̞ͬܳ̀ȃ ̹̺̱Ȃ ౿ྵഎ̈́అ‫͉ٺ‬ဓ̢̞̈́͢ȜͅȊġ̩̪͇ͦͦ͜Ȋ

さてこれ、「UNIX は知育玩具『こわしたい放題』だ !」と題したお題なんですが、UNIX やコマンド制作者のコメントによると、全角半角混じっている場合……

想定を超えた使い方をした時に起こる変な動作を見つと悩み始めたらゴチャゴチャになっちゃったそうで。

けて楽しもうという趣旨です。これもいくつか投稿き

そうか、言われてみれば確かにねぇ。出題時にそこましたが、まぁ皆さんよく見つけますねぇ。

まで想定してなかった！ 半角文字ができれば OK。申※ 編集部よりご注意

し訳ない !! 労をねぎらってඵ౲਎ဓ。これで三段だ。

重要な役目を担ったサーバー、その他再起動させられてɝ̤ਈ‫ؚ͈̯ͭ‬ٜ൞

は困るホスト上では、このお題で投稿されたコードは動2!$"0cjo0cbti
3!
4!dbu!%2!!!!!!!!!!!!!!!!!!!}
5!tfe!(t0_!+00(!!!!!!!!!!!!}
6!bxl!(|qsjou!mfohui)%1*~(!}
7!tpsu!.l2-2os!!!!!!!!!!!!!}
8!ifbe!.2!!!!!!!!!!!!!!!!!!}
9!dbu!.!%2!!!!!!!!!!!!!!!!!}:!tfe!(t0_!+00(!!!!!!!!!!!!}
21!bxl!(OS>>2|ibcb>%2~<22!!!!!!OS">2|zpiblv>jou))ibcb.mfohui)%1**03*<
23!!!!!!!!!!!!gps)j>2<j=>zpiblv<j,,*|qsjoug!#!#~<
24!!!!!!!!!!!!qsjou!%125!!!!!!!!!!!~(

かさないでください。

こちらは、パイプを駆使してうまいことスッキリ書

ディスクを破壊するなど、再起不能にするような投稿はありませんが、プロセスが壊れるなどしてOSの再起動を余儀なくされる可能性が無いとは言えません。

ɝͼΗυȜ̯͈ٜͭ൞
%! nlejs!iphf%! de!iphf%! upvdi!1%! gps!o!jo!%)tfr!1!211111*<!ep!mo!%o!%))o,2**<!epof

こーいうお題の時はいつもこの方から来ますね。毎度ありー！

さて、このコマンドを実行に際して確認けてますねぇ。length($0) とやっているので全半角のした動作環境は「Fedora19 上の bash と FreeBSD 9.2

区別無しなわけですが、やはり半角文字だけと割り上の sh」とのことです。

切ってしまえば簡単に書けるのでしょうか。
うーん、すっきり書けたもう一つのポイントは元なるほど、ハードリンクをどこまで作れるか試したのね。やってみたら 32767 個しか作れなかったよ。

データを実ファイルとして二か所 (3 行目と 8 行目 )OS の制約なのかねぇ。面白い、֚౲਎ဓ。

で開いてるからかな。うまい。֚౲਎ဓ。只今六段。

ɝͼΗυȜ̯͈ٜͭ൞

ɝŨŰųŪįŴũ ̯͈ٜͭ൞

%! b>%)zft!UblbtvDmjojd!}!ifbe!.21111111}us!.e!(]o(*%! fyqpsu!b%! zft2!$"!0cjo0ti
3!tfe!(t0_0/UI!##!##!##!##!0(!?!0unq0nbo%%
4!nbo!0unq0nbo%%!}!tfe!.o!(t0_)*0!!0q(!}!tfe!(t0)*

連続投稿。動作環境は同じだそうですよ。

MAGA INE 2014
MAGAZIN014
4 winterwin er72 USP MAGAZINE

69̲73̲shogiri11.indd 72

2013/12/10 18:47:17

徹底仕事術！
仕事術！
C U I 徹底仕ΏͿσΑ·ςίΠఱ‫ܔ‬၌
えぇと今度は何だい？環境変数にバカデカい文字列

これは、面白い。੝౲਎ဓ。

をぶち込んで、他のコマンドに食わせるってわけか。

◇

◇

◇

今 度 は “Argument list too long” に な っ た ぞ。 へ ぇ、といったろころで本日の大喜利はこれにてお開き！

こんなことになるのか。ただ、true とか false とか、十段達成者が出てめでたいねー。読者の皆さん、投稿

影響受けないコマンドもあるね。引数をとるかとらな

してくれた皆さん、今回もありがとうございました。

いかかな？

よし、これも֚౲਎ဓ。これで三段だ。

ൎࣂఱ༡ਬɝ‫׺‬ඵ࣢̯͈ٜͭ൞
%! usvodbuf!.t!211111111111111!CJHEBUB%! wj!CJHEBUBষ͈̤ٝఴ

猿二号さんもこの手のお題の常連さんですね。あり֚Ȃġ1 〜 n（n は引数で指定）の自然数の中に存在するがとうござます。動作環境は「truncate コマンドがあ「安全素数」を列挙するシェルスクリプトを書いてるコンピューター上ならたぶんどこでも動きます」とください。

のことでした。

ඵȂġ16 行 16 桁のテキストファイルがあります。この今ハヤリのビッグデータか ( 違 )。えぇと、s オプショ

外周部に 0~9, A~Z, a~x の 60 個の英数字が記さ

ンの数字は何桁あるんだ。一、十、百、千、万、…、っ

れており、内部（14 × 14）は全て空白文字です。

て Ĳıı Ξρ̥̞Ȋġ こんなに大きなデータ作ったら 1

このようなテキストを与えると、外周を時計回り行目を実行した時点でディスクが溢れるでしょと思っに 1 文字移動させるシェルスクリプトを書いてくたら、違うのね。“mt!.mi” って実行するとファイルサださい。

イズは 91T とか表示されるものの、実際のディスク२Ȃġ今 回の解答に ping コマンドで時間を稼ぐものが領域は食っていないらしい。でも、vi はマジメに読みありましたが、他の何らかのやり方やコマンドで、込もうとするのね。それでメモリを喰いまくる、と。

時間稼ぎをするための方法はありませんか。ただスワップしたら負けなマシンなのにスワップしまく
ちゃったじゃないか。プロセス殺すのも一苦労だったよ。あぁ酷い目に遭った。これは̻̽͂͡΅Ήϋٜ̈́൞̛̺̈́ȃ ൲ै͉ুࡨୣහ͇́Ȋとはいえ、truncate コマ
ンドの動作は興味深かったし、֚౲਎ဓだ。現在五段。

ɝչऎाࠠ໤̯͈ٜͭ൞
%! fwbm!mt!%)zft!(}dbu(!}!ifbe!.4444!}!us!.e!(]o(*!}!
dbu

ユニークなお名前ですね。投稿コメントによれば、

し、次のようなリクエストがあります。
ͼȂġある程度の精度で秒数を予測できる ( 従って単純なループによる時間稼ぎはダメよ )υȂġ珍しいもの大歓迎（sleep とかはちょっとねぇ）

ൎࣂ͈̱̥̹
お題への解答は、お名前（ペンネーム）、解答した
いお題番号、解答スクリプト、簡単な補足の四点セッ
トで下記の宛先へ。一人何問でも何個でも解答可！

動作環境は bash 3.2、テーマは「bash でパイプは何尚、
次回締め切りはˎ࠮ˎĵ ඾Ȫ࠮ȫࡿஜ ı শとします。

本繋げるか」とのことです。そして肝心の結果は、しかもその間は何度でも解答の修正を受け付けます。

3333 本だったそうです。
（上記の 3333 を一つ減らして 3332 にすると正常に動くそうです）

̤ఴ̱̱̓̓͜௣̩̺̯̽̀Ȝ̞

へぇー、こりゃまた興味深い。でもこれって「単純に、お 題 の 投 稿 も 大 募 集。 こ っ ち は 締 め 切 り な し でコマンド一行として書ける文字列長の制約に引っ掛ずーっと募集中。そして、考えてくれた方にも段位をかってるんじゃないの？」とも思ったんだけど、“dbu”

授与します。自分で出題して解答するのも、OK ！

を “dbu! .” に替えてもやっぱり 3332 と 3333 の間に境界があるんだよね。どうやらホントにパイプの本数みたい。気になったんで同じホスト上で他のシェルで

ൎࣂ୶
どちらも投稿先は、も試してみたんだけど、例えば dash だともっと多く白ければ（ワリと）何でもあり！

ても平気だし、逆に zsh だと 2000 でもダメだったね。

待ってます !

です。面じゃんじゃん投稿

73
7
3

69̲73̲shogiri11.indd 73

2013/12/10 18:47:18

USP 友の会

winterVol.11

編集長

松浦智之
副編集長

青井大地
編集

柏崎吉一

鎌田広子

星春菜

縫 製 の 仕 事 を 夫 婦 で や っ て い た。 僕
仕事の原点
― シェル魔人―の仕事は大阪で仕入れた鞄の部材とな る 布 や、 仕 事 先 で 受 け 取 っ た 鞄 製
僕は現在IT会社の社長をやって品を叔父さんのトラックに積み込む
いるが、これは偶然だ。
ことだった。
時 代 も 昔 と い う こ と も あ っ た が、
ト ラ ッ ク の 助 手 席 に 乗 っ て、 叔 父コンピュータとの出会いは大学にさんから色んな仕事の話を聞かされ
入 っ て か ら で、 遅 め だ っ た。 先 輩 がた。その中で印象に残ったのは、「時
パソコンに向かってキーボード入力
間さえ守っていれば仕事になる」「世
し て い る の を 見 て、「 テ レ ビ に 向 か っの中で数を正確に数えることが一番て 英 語 を 勉 強 し て い る 」 と 言 っ て、 難 し い 」「 誰 も 見 て い な く て も ど ん
失笑を買ったくらいだ。
な こ と で も 一 生 懸 命 や っ て い る と、
金 欲 し さ に「 コ ン ピ ュ ー タ が で き
不 思 議 な こ と に 誰 か 見 て い る 」と いる」と嘘をついて、先輩の後をつけて、 う も の だ っ た 。
ソ フ ト 会 社 の ア ル バ イ ト を 始 め た。
当 時 高 校 生 だ っ た 僕 は、 毎 朝 学 校
嘘 を 真 に す る た め に、 速 攻 で ア セ ン
へ 定 時 に 行 く の は 当 た り 前 だ っ た し、
ブ ラ 言 語 を 覚 え た。 先 輩 の パ ソ コ ン
ちょっと数学が出来て得意だったのの キ ー ボ ー ド の 絵 を 紙 に 書 き 写 し て、 で、 数 の こ と は、 正 直 叔 父 さ ん が 何
タッチタイピングの練習をしながらを言っているのか分からなかった。
の ス タ ー ト で あ っ た。 今 だ と 笑 い 話
し か し あ る 日、 僕 は 大 失 敗 を し てだ が、 こ の 時 の 経 験 が コ ン ピ ュ ー タ
し ま っ た。 朝 ３ 時 で ま だ 暗 く、 大 阪の仕事の原点だった。
で布を１５００枚数えてトラックに詰 め 込 む 仕 事 だ っ た の だ が、 時 間 がか か っ た 上 に、 数 を 間 違 っ て し ま った。 ト ラ ッ ク で 何 時 間 も か け て 走 っ

制作協力

當仲寛哲

（ジーズバンク）

定価 500 円（本体価格 476 円）
発行元 （有）USP 研究所

ご意見・ご感想・投稿はこちら（技術的なお問合せには対応しかねますので

mag@usp-lab.com

そ れ か ら、 僕 は 何 十 と い う 仕 事 を
経 験 し て き た が、 そ の 底 辺 に 流 れ るの は、 や は り 叔 父 さ ん の 言 葉 だ。 僕は 今 で も お 酒 が 入 る と、 若 い 人 に 当時の話をしてしまう。
ど ん な 仕 事 で も プ ロ が い て、 そ の
熟 練 た る や、 す ご い も の だ。 清 掃 の仕 事 で も 皿 洗 い で も、 ビ ラ 配 り で もだ。 叔 父 さ ん の 言 葉 に 従 い、 ど ん な
仕 事 で も、 誰 が 見 て い な く て も 僕 は一生懸命やることをモットーにしてきた。
そ れ は、 今 の 仕 事 に も つ な が っ ていると思う。それが何であってもだ。

た契約先で、大好きな叔父さんが謝って い る 後 ろ 姿 を 見 て、 あ あ、 自 分 の責 任 だ、 と も の す ご く 情 け な い 思 いをした。
ア タ マ で っ か ち だ っ た 僕 は「 取り返しのつかない」とはこういうこと だ、 と 思 っ た。 ア タ マ の 中 の 話 と、実際に手足を動かして時間に間に合 わ せ る と い う の は、 完 全 に 別 物 だ、
そう感じた。

発行人

石塚幸治
表紙デザイン

9:15:50

2013/12/27

75

USPMAG201312_h1-4_cs55.indd

2014

高 校 生 の 時 は、 叔 父 さ ん の 仕 事 を
ア ル バ イ ト で 手 伝 っ た。 叔 父 さ ん は

USP MAGAZINE info

USP マガジンFB
USP MAGAZINE の最新・詳細な情報はこちら。
読者アンケートにも是非ご協力を。

USP
MAGAZINE

ご了承ください）編集後記

・古代から道は人馬の移動により形作られた。誰も通らなければ道は廃れる。いま足下、眼下にある道も無数の何者かが通り続けた証だろう。路上で起きた出来事を逐次書き留めていれば長大な年表ができそうだ。泥酔して寝込んだり迷惑をかけたりした人間は書き切れないほどいたに違いない。年末は特に（柏崎＠エクリュ）
・ところ変われば品変わる。今回 IT 美女図鑑がない理由なのですが、vol.11 制作中に地球の裏側、チリのサンチアゴ
へ遊びに行ってきたのです。どうだったか？ net-cafe に行ったのですが、2byte の表示できないブラウザとか久しぶりでした。雨は 1 回だけ降りました。8 月ぶりだったそう。
（鎌田）
・早いものでもう年末ですね。毎年年賀状はお絵かきしたものを印刷して送っているんですが、ここ何年かはお正月
を大分過ぎてからの作業になってしまってます。来年は午年！今回こそはせめて三が日中にお届けできるように仕上げたいところです (@̲@;)…お、おそくても 7 日までには…！！！（星）・先月再び沖縄へ出張。経費節約ということで、なるべくバスで移動したが、目的地へ行く便がなかなか来ないことも。
知らない土地、暗いバス停で過ぎ去る車の光を眺めつつ、バスを延々と 30 分以上待つ。そして乗ってからも渋滞で進まず、1 時間以上かかってホテルへ。忍耐力はこうして鍛えられる？ それが役に立つ仕事だ、編集者は（青井）・できた。雑誌じゃなく、前回の編集後記で豪語してたショッピングカートが。当然シェルスクリプト製。PayPal 決済にも DL 販売にも対応。さぁ早くこれで本誌を売りたい！が、特集でご覧の通り多数のツッコミが……。3 年間の取材を通して作法はだいぶ勉強したはずだったのに。早く直して使いたい。
（松浦）

75

USP MAGAZINEUSP MAGAZINE 2014 winter Vol.11

超高速開発は、IT 従事者の業務内容から企業経営までを大きく変える可能性があります。
このコミュニティではツールベンダーとユーザー企業の意見交換を通して、超高速開発の普及とビジネスの変革に貢献します。
スーパープログラマーたる皆様のご参加を心より歓迎します。

技術の草原で百獣の王を目指す
シェルスクリプトを極める勉強会コミュニティ（会員数：約 480 名）

http://www.usptomo.com/

エンジニアたちの新感覚トークライブ！

http://techlion.jp/

USP MAGAZINE バックナンバー 好評発売中 !
vol.0 2011 spring~vol.6 2012 autumn

vol.7 2013 winter

突

新

す

好

です。

USP MAGAZINE は、
世界初のシェルスクリプト技術情報誌。でもご存知のとおり、シェルスクリプトはグルー言語。
OS 深層から様々な言語・アプリの話まで、さらには技術の先にいるエンジニア達にもスポットを当てます。
目指すは、シェルスクリプト力とエンジニア達の地位向上！

定期購読又はバックナンバーをお申込みいただくと、PDF 版が無料で手に入ります。
ご購入、お申込みはこちらから⇒

USP 出版

大

定価 500 円（本体価格 476 円）

なさい
在庫終了

「
何

U

「
Vol.11USPMAG201312_h1-4_cs55.indd76

2013/12/27

9:15:42

熊「デvol.8 2013 spring vol.9 2013 summer vol.10 2013 autumn

ごめん

自炊不要

特

2014 winter発行人 當仲寛哲
発行・発売 有限会社ユニバーサル・シェル・プログラミング研究所〒105-0003 東京都港区西新橋 3-4-2 SS ビル 3 階 電話 03-3432-1174 発行日 2013 年 12 月 20 日

TechLIONUSP 友の会UMf

https://www.x-rad.jp/※ 2014 年 1 月 23 日のセミナーで USP 研究所が慶應大学様の事例を初公開！ https://www.x-rad.jp/eventmenue/コ