ちょっとしたシェルスクリプト

UNIX系OSの利点は,強力なコマンドライン処理にあります.コマンドを組み合わせてシェルスクリプトを作っておけば,ある決まった処理を自動的にやってくれて便利です.ここでは,ちょっとしたシェルスクリプトを紹介します.

シェルスクリプトの実行方法

以下で紹介するスクリプトはbashとperlを使っています.だからそれらがインストールされている場所で使えます(Linuxならたいてい最初から入っています).実行するにはまずchmodで実行属性を持たせます.たとえばfooというファイル名なら

$ chmod +x foo

とすることで実行属性がつきます.実行にはfooと同じディレクトリで

$ ./foo

とします.パスの通ったディレクトリに実行ファイルを置けばどこからでも実行できるようになります.ユーザのホームディレクトリ直下に bin という名前のディレクトリを作成してパスを通し,そこに細々としてシェルスクリプトをまとめておくのが一般的です.

文字コード変換

LinuxのTeXは,日本語が入っている場合,その文字コードがEUCでなければコンパイルできません.一方,WindowsでのTeXは文字コードがShift-JISでなければコンパイルできません.両者で同じソースを使用したい場合,文字コードを一括して変換できれば便利です.

Shift-JISに変換

#!/bin/sh
while [ -n "$1" ]; do
	if [ -e "$1" ]; then
		TMPFILE=nkftmp$$
		nkf --windows $1 > $TMPFILE
		mv  $TMPFILE $1
		echo $1
	fi
	shift
done

EUCに変換

#!/bin/sh
while [ -n "$1" ]; do
	if [ -e "$1" ]; then
		TMPFILE=nkftmp$$
		nkf --unix $1 > $TMPFILE
		mv  $TMPFILE $1
		echo $1
	fi
	shift
done

HTML関係

HTMLファイルそのものはテキストファイルですから,正規表現などを用いて様々な処理を自動化することが可能です.

htm2html

僕はHTMLを書きはじめた頃,拡張子を .htm としていました.しばらくしてから .html の方が一般的だと分かってそうしましたが, .htm のものがまだ残っていたりします.昔つくったサイトはまるごと .htm のものもあります.

変更したいファイルが少しならファイル名を一つずつ変更して,HTML 内のリンク「<a href="file.htm">」を「<a href="file.html">」に換える作業も手でやっていいのですが,サイトまるごと直したりするのは大変です.そこで一括してファイルの拡張子とHTML内のリンク先を変更するスクリプトを作りました.

#! /bin/sh
test -z "$1" && echo "Usage: htm2html <directory>" && exit
cd "$1"

# .htm を .html に変換する
find . -maxdepth 1 -type f -name '*.htm' | while read htm; do
    echo "$htm"  # 進行状況を表示
    mv "$htm" `basename "$htm" .htm`.html
done

# HTMLファイルの内容を書き換える
find . -maxdepth 1 -type f -name '*.html' | while read html; do
    # HTMLファイルの内容をperlで置換
    perl -i -p0777e "s/(<*\s.*?)(src=|href=)(['\"]?)(.*?).html*/\$1\$2\$3\$4.html/gi" "$html"
done

最初のループは,find コマンドで拡張子が .htm のファイルを見つけ, mv コマンドで拡張子を .html に変換します.二つめのループでは .html のファイルの内容を perl の正規表現で調べ,リンク先が .htm の部分を .html に置換しています.

find で -maxdepth 1 としているので,サブディレクトリに関してはいじりません.サブディレクトリを含めてディレクトリまるごと変換したいときは,対象のディレクトリに移動して

$ find . -type d -exec htm2html {} \;

と find コマンドから実行します.これはカレントディレクトリ以下から(.)ディレクトリだけを探して(-type d)htm2html というコマンドに,検索されたディレクトリを渡して実行しています(-exec htm2html {} \;).

htmlconv-sjis

UNIX系OSでの文字コードはEUCが標準なので,なにも考えずEmacsなどのエディタでHTMLを書いていると, EUCでファイルを保存することになります.しかしWindowsやMacでの標準文字コードはShift_JISです.互換性のため,文字コードをEUCからShift_JISに変換したいことは良くあります.

#! /bin/sh
test -z "$1" && echo "Usage: htmlconv-sjis <directory>" && exit
cd "$1"

# HTMLファイルの文字コードを変換する.
find . -maxdepth 1 -type f -name '*.html' | while read html; do
    echo "$html"  # 進行状況を表示
    # eucに変換
    tmpfile=`basename "$html" .html`$$.html
    nkf -s -Lw $html > $tmpfile
    mv "$tmpfile" "$html"
done

# HTMLファイルのヘッダを書き換える.
find . -maxdepth 1 -type f -name '*.html' | while read html; do
    # perlで置換
    perl -i -p0777e "s/(<meta\s.*?charset=)\w.*(['\"])/\$1Shift_JIS\$2/gi" "$html"
done

このスクリプトは引数で指定したディレクトリ内の拡張子が .html のファイルの文字コードを, nkf を使って Shift_JIS に変換します.ここで改行コードは Windows 標準の CR+LF にしています.それと HTML ヘッダの charset="xxx" の xxx の部分を Shift_JIS に書き換えます.

htmlconv-euc

htmlconv-sjis をちょっと変更したら,EUC へ変換するものもできます.

#! /bin/sh
test -z "$1" && echo "Usage: htmlconv-euc <directory>" && exit
cd "$1"

# HTMLファイルの文字コードを変換する.
find . -maxdepth 1 -type f -name '*.html' | while read html; do
    echo "$html"  # 進行状況を表示
    # eucに変換
    tmpfile=`basename "$html" .html`$$.html
    nkf -e -Lu $html > $tmpfile
    mv "$tmpfile" "$html"
done

# HTMLファイルのヘッダを書き換える.
find . -maxdepth 1 -type f -name '*.html' | while read html; do
    # perlで置換
    perl -i -p0777e "s/(<meta\s.*?charset=)\w.*(['\"])/\$1EUC-JP\$2/gi" "$html"
done

これらのスクリプトも,サブディレクトリに関してはいじりません.

htmltex-arrange

LaTeXで書いた文書をHTMLに自動変換してくれるLaTeX2HTMLというソフトがあります.非常に便利なのですが,出力されるHTMLはいささか素っ気ない感じがします.自分のスタイルシートを適用するだけで,ずいぶん見栄えが変わって来ますので「<link REL="STYLESHEET" HREF="xxx.css">」の xxx.css の部分を変換するスクリプトをつくりました. LaTeX2HTML で自動生成される HTML ファイルでは,xxx.css の xxx の部分は LaTeX 原稿ファイルのファイル名になっています.それを自分でつくったスタイルシートファイル(の場所)「../../../latex.css」に置き換えます.

それと,僕はいつも <body> タグの直後に <div class="box"> を付けてページ全体をレイアウトしているので,それも付け加えます. </body> タグの直前に </div> を付けて閉じています.

#! /bin/sh
test -z "$1" && echo "Usage: htmltex-arrange <directory>" && exit
cd "$1"

find . -maxdepth 1 -type f -name '*.html' | while read html; do
    echo "$html"
    perl -i -p0777e "s/<body\s.*?\w.*?>/<body><div class=\"box\">/gi" "$html"
    perl -i -p0777e "s/(<link\s.*?HREF=)(['\"]?)\w.*.css/\$1\$2..\/..\/..\/latex.css/gi" "$html"
    perl -i -p0777e "s/<\/body>/<\/div><\/body>/gi" "$html"
done

このサイトの 物理公式集 などは htmltex-arrange を使ってアレンジしています.楽です.なお,スタイルシートの指定のみなら,latex2htmlのオプション

-style cssのパス

で対応できます(HTMLにも手を加えたいなら,スクリプトで処理するしかありません).

サイト引っ越し時のHTML生成

#!/bin/sh

BASEHREF=http://hooktail.org/sakima/125cc

while [ -n "$1" ]; do
	if [ -e "$1" ]; then
		TMPFILE=nkftmp$$
		FILENAME=$1
		URL=$BASEHREF/$FILENAME
		: > $1
		cat > $1 <<- END
			<html>
			<body>
			<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
			<title>移転しました</title>
			</head>
			<body>
			<p><a href="$URL">$URL</a> に移転しました m(_ _)m</p>
			</body>
			</html>
		END
		lv -Ou8 $1 > $TMPFILE
		mv  $TMPFILE $1
		echo $1
	fi
	shift
done

その他

raumen

研究室での食事といえばカップラーメン. 3分後に音が鳴るアラームがあると便利です.

#! /bin/sh
sleep 160 && perl -e 'print "\x07"; print "Raumen is available!!\n"'

これを実行すると指定時間後にビープ音がピッと鳴ります.変なメッセージも出します.僕は硬めが好きなので2分40秒に設定しておきました.余計なお世話ですか.

参考リンク

このページのシェルスクリプト書くにあたって,つぎのサイトを非常に参考にしました(ほとんど丸写しの部分もあります).どうもありがとうございます.

Valid XHTML 1.1! home > コンピュータ > プログラミング >
リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Modified by 物理のかぎプロジェクト PukiWiki 1.4.5_1 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-jiPowered by PHP 5.2.17HTML convert time to 0.059 sec.