空フォルダ・ディレクトリを削除する


(ORESAMA / 流星ダンスフロア)

アニメ『魔法陣グルグル』(2017)の主題歌です。
ORESAMAの歌から入って、アニメを見たのですが、すっごい面白いですこれ。

今回は、空フォルダ・ディレクトリの削除です。
フォルダ・ディレクトリが空かどうか知るには、ディレクトリをぐるぐる巡回しないといけないわけですが、まあLinuxでは面倒なことはすべてfindコマンドがやってくれます。

まずは実験用ディレクトリを作っておきましょう。適当に数階層のディレクトリ、各階にファイルを生成。

takk@deb9:~/tmp$ mkdir -p dir1/111/222/333/444
takk@deb9:~/tmp$ mkdir -p dir1/aaa/bbb/ccc/ddd
takk@deb9:~/tmp$ for i in `find`;do touch $i/file.txt;done
takk@deb9:~/tmp$ find
.
./dir1
./dir1/file.txt
./dir1/aaa
./dir1/aaa/bbb
./dir1/aaa/bbb/ccc
./dir1/aaa/bbb/ccc/file.txt
./dir1/aaa/bbb/ccc/ddd
./dir1/aaa/bbb/ccc/ddd/file.txt
./dir1/aaa/bbb/file.txt
./dir1/aaa/file.txt
./dir1/111
./dir1/111/file.txt
./dir1/111/222
./dir1/111/222/333
./dir1/111/222/333/file.txt
./dir1/111/222/333/444
./dir1/111/222/333/444/file.txt
./dir1/111/222/file.txt
./file.txt
takk@deb9:~/tmp$

さらにディレクトリを増やして、一部ファイルを削除して、空ディレクトリを作っておきます。

takk@deb9:~/tmp$ cp -r dir1 dir2
takk@deb9:~/tmp$ find dir2/aaa -type f | xargs rm
takk@deb9:~/tmp$ 

後で比較するため、この状態のディレクトリの一覧を保存しておきます。

takk@deb9:~/tmp$ find -type d > origin
takk@deb9:~/tmp$

では、空ディレクトリを抽出しましょう。-emptyオプションで抽出できます。

takk@deb9:~/tmp$ find -type d -empty
./dir2/aaa/bbb/ccc/ddd
takk@deb9:~/tmp$

削除するには、-deleteオプションも併用します。
すべての空ディレクトリが削除されます。

takk@deb9:~$ find . -type d -empty -delete

元のディレクトリ一覧と比較してみます。

takk@deb9:~/tmp$ find -type d | diff origin -
12,15d11
< ./dir2/aaa
< ./dir2/aaa/bbb
< ./dir2/aaa/bbb/ccc
< ./dir2/aaa/bbb/ccc/ddd
takk@deb9:~/tmp$

空ディレクトリのみ消えてますね。

では、Windowsです。
Linuxと同じように、実験用フォルダ作ります。

C:\Users\takk\tmp>mkdir dir1\111\222\333\444
C:\Users\takk\tmp>mkdir dir1\aaa\bbb\ccc\ddd
C:\Users\takk\tmp>powershell "gci -r -n -ad | % {ni -itemtype file $_/file.txt}"
C:\Users\takk\tmp>powershell "cp -r dir1 dir2"
C:\Users\takk\tmp>powershell "cd dir2/aaa;gci -r -n -af | % {rm $_}"
C:\Users\takk\tmp>

削除前フォルダ一覧として保存しておきます。

C:\Users\takk\tmp>powershell "gci -r -n -ad > origin"

ファイルが存在するかどうかは、ファイルを抽出した時のオブジェクト数が0かどうかで判断すればよいです。各フォルダに含まれるファイル数を一覧表示してみます。

C:\Users\takk\tmp>powershell "cd dir2;gci -r -n -ad | %{Write-Host $_ (gci -r -n
 -af $_).count}"
111 4
aaa 0
111\222 3
111\222\333 2
111\222\333\444 1
aaa\bbb 0
aaa\bbb\ccc 0
aaa\bbb\ccc\ddd 0

C:\Users\takk\tmp>

次は、カウントが0かどうかの真偽一覧。

C:\Users\takk\tmp>powershell "cd dir2;gci -r -n -ad | %{ Write-Host ( (gci -r -n
 -af $_).count -eq 0 ) $_}"
False 111
True aaa
False 111\222
False 111\222\333
False 111\222\333\444
True aaa\bbb
True aaa\bbb\ccc
True aaa\bbb\ccc\ddd

C:\Users\takk\tmp>

真偽分かれば、ファイルが存在しないフォルダが分かるので、削除するだけです。

C:\Users\takk\tmp>powershell "cd dir2/aaa;gci -r -n -ad | %{ if( (gci -r -n -af $_).
count -eq 0 ){rm -r $_}}"

C:\Users\takk\tmp>

元フォルダの一覧と比較してみます。

C:\Users\takk\tmp>powershell "$a=cat origin;$b=(gci -r -n -ad);diff $a $b"

InputObject                             SideIndicator
-----------                             -------------
dir2\aaa\bbb                            <=
dir2\aaa\bbb\ccc                        <=
dir2\aaa\bbb\ccc\ddd                    <=



C:\Users\takk\tmp>

この通り、空フォルダがきれいに消えました。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA