Thursday, May 21, 2009 / Bash, Jython, Make

Makefileでカレントディレクトリ内のディレクトリだけを抽出して使う

ブログ管理用の Makefile を書いているのだが、カレントディレクトリ以下にあるサブディレクトリだけを列挙したい。 サブディレクトリは、時間とともに変化するので、Makefileに直に書くのはやめたい。

Cygwin版

ls,awk,grep を組み合わせてサブディレクトリを列挙

ls -l するとディレクトリ情報とともにカレントディレクトリのファイルリストが得られる・・・以下のように。

$ ls -l
-rwxr-xr-x  1 moca None  65289 May 20 16:58 archive.html
drwxr-xr-x+ 7 moca None 524288 May 21 06:05 blog
drwxr-xr-x+ 2 moca None      0 May 19 13:13 css
drwxr-xr-x+ 3 moca None   4096 May 21 06:05 framemaker
drwxr-xr-x+ 3 moca None   4096 May 21 06:05 google
drwxr-xr-x+ 2 moca None      0 May 13 22:59 icons
drwxr-xr-x+ 3 moca None   4096 May 21 06:05 illustrator
-rwxr-xr-x  1 moca None  97922 May 20 17:22 index.html
drwxr-xr-x+ 2 moca None      0 May 13 22:59 js
drwxr-xr-x+ 3 moca None   8192 May 21 06:18 memo
drwxr-xr-x+ 2 moca None   4096 May 13 22:59 myicons
-rwxr-xr-x  1 moca None   2717 May 20 21:08 myutils.py
-rwxr-xr-x  1 moca None   1295 May 20 21:05 root-archive.py

この結果を awk と grep を使って処理

$ ls -l | awk '{print $1,$9}' | grep "^d" | awk '{print $2}'
blog
css
framemaker
google
icons
illustrator
js
memo
myicons

これでほとんど目的は達成したのだが、css,icons,js,myicons は取り除きたい。

$ ls -l | awk '{print $1,$9}' | grep "^d" | awk '{print $2}' | egrep -v "^css|^icons|^js|^myicons"

egrep を使うのがポイント、grep では or の正規表現を使うことができなかった。

こちらのページによれば | を エスケープすれば grep でも 正規表現の or が使えるらしい。)

Makefile の中で使う

上記結果をふまえて、カレントディレクトリにあるサブディレクトリを列挙した結果を Makefile内で使います。

Makefile

subdirs という単純変数にサブディレクトリをセットします。

subdirs := $(shell ls -l | awk '{print $$1,$$9}' | grep "^d" | awk '{print $$2}' | egrep -v "^css|^icons|^js|^myicons")

test :
        @echo $(subdirs)

Jython 版

このMakefileをCygwinだけでなく、Ubuntu(Linux)でも使うようにしたら、意図通り動かなくなった。 Jythonで同じ機能を果たすコードを書き直した。

subdirlist.py

現在のディレクトリ内にあるディレクトリを列挙するJythonコード。

import java

SKIPDIRS='css,icons,js,myicons'

def isSkip(name):
	for skipdir in SKIPDIRS.split(','):
		if name==skipdir :
			return True

	return False


for f in java.io.File('.').listFiles() :
	if f.isDirectory():
		dirname= f.name
		if isSkip(dirname)==False :
			print dirname

※SKIPDIRS に列挙対象から除外したいディレクトリ名を入れておく。

Makefile

subdirlist.pyの実行結果を subdirs 単純変数に格納。

subdirs := $(shell jython subdirlist.py)

test :
     @echo $(subdirs)