Index > Makefileでカレントディレクトリ内のディレクトリだけを抽出して使う(サブディレクトリのみ列挙)
Thu, May 21, 2009

Makefileでカレントディレクトリ内のディレクトリだけを抽出して使う(サブディレクトリのみ列挙)

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

2009-07-08 追記

Cygwinだけでなく、Ubuntu(Linux)でもこのMakefileを使ったところ、CygwinとUbuntu で ls の出力形式が異なるため ここで説明した方法では、うまくディレクトリをリストアップできなくなってしまった。
Jython を使った代替案

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)

groovy 版

Jython版はサブディレクトリを列挙するコードがMakefileとは別に必要になってしまうため そのことが不便なこともあります。

groovyでは、サブディレクトリ列挙を一行で表現する方法により、Makefile内で完結させてみました。

$ groovy -e "new File('.').listFiles().each{ if( it.isDirectory() ){ println it } }

Makefile

subdirs := $(shell groovy -e "new File('.').eachDir{ println it }")

test :
    echo $(subdirs)

.svn サブバージョンの管理ディレクトリを対象から外す場合

$ groovy -e "new File('.').eachDir{ if(!it.name.startsWith('.svn')){ println it } }
 Twitter
follow me on Twitter
 Categories