Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

mkdirの -p オプション相当を実現するには?

120 views
Skip to first unread message

Kazuhiko Nanmei

unread,
Apr 2, 1998, 3:00:00 AM4/2/98
to

こんにちわ
なんめい@東芝と申します。

mkdirの-pオプション相当を実現したいのですが、どんなふうに
書けば良いんでしょうか?
 どなたか、ご教授ください。m(__)m

やりたい事は・・・
カレントディレクトリに、「a」というディレクトリが無い状態で

mkdir -p a/b/c/d

とやった場合、カレントディレクトリに、a、その下に、b、その下に、c、・・・
という風に、勝手に足りないディレクトリを作ってくれますよね。
それを、

mdkir a/b/c/d

とやると、当然のように・・・

mkdir: ディレクトリ "a/b/c/d" を作成できません: ファイルまたはディレクトリがあ
りません。
とエラーになります。

でも、どうにかして「-p」オプションを使わないで、
同じような事をやりたいのです。

実際使うコマンドは、mkdirでは無く、他の外部コマンドなんですが・・・
また、そのコマンドが、-pの様なオプションを実装してくれていなんで
困ったしだいです。

宜しくお願いします。


IRIUCHIJIMA Ken / 入内島 健

unread,
Apr 2, 1998, 3:00:00 AM4/2/98
to

>>>>> kazuhik...@toshiba.co.jp (Kazuhiko Nanmei) (="nammei") さん
>>>>> 2 Apr 1998 10:09:48 GMT に言われるには:

nammei> mkdirの-pオプション相当を実現したいのですが、どんなふうに
nammei> 書けば良いんでしょうか?
...

nammei> mkdir -p a/b/c/d

ばらして、上から順番にあるかどうか試しながら作っていけばよいですね。
区切りが '/' なので若干面倒ですが考え方だけ書くと、$_ に a/b/c/d が入っ
ているとして

@d = split m'/';

for (@d) {
mkdir $_
unless -d $_;
chdir $_;
}

みたいなことをやれば、できるでしょう。
# このまま全く加筆なしに動くとは思わないで下さいね。
--
東芝 入内島 健 横浜市鶴見区在住
mailto: ken.iri...@toshiba.co.jp, junkto: k...@gaea.ssel.toshiba.co.jp

m-a...@mxa.meshnet.or.jp

unread,
Apr 2, 1998, 3:00:00 AM4/2/98
to

東です。

<6fvo5c$j...@ux37.fuchu.toshiba.co.jp>の記事において
kazuhik...@toshiba.co.jpさんは書きました。

> mkdirの-pオプション相当を実現したいのですが、どんなふうに
> 書けば良いんでしょうか?

"`"を使ってシェルで実行すればよいわけですから、

`mkdir -p a/b/c/d`;

でどうでしょう。
--
東 正記 <m-a...@mxa.meshnet.or.jp>

Hideki OHTA

unread,
Apr 2, 1998, 3:00:00 AM4/2/98
to

 太田@名古屋大学です。

fj.lang.perl の "mkdirの -pオプション相当を実現するには?" の記事
<6fvo5c$j...@ux37.fuchu.toshiba.co.jp>において
1998年04月02日(木曜日) 19時09分48 秒頃、Kazuhiko Nanmeiさん
(kazuhik...@toshiba.co.jp) は書きました。

>> こんにちわ
>> なんめい@東芝と申します。
>>
>> mkdirの-pオプション相当を実現したいのですが、どんなふうに
>> 書けば良いんでしょうか?

perl5 であれば、(perl -v で確認できる) File::Path モジュールが使えます。

use File::Path;

mkpath 'a/b/c/d';
mkpath ['hoge/hoge', 'foo/bar'];

また、File::Path モジュールには、あるディレクトリ以下の前ファイルを消す
rmtree 関数も提供されています。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
太田 秀樹 (名古屋大学 工学部 電気電子・情報工学科 4年)
情報処理教育センター アシスタントスタッフ
e-mail:ho...@eds.ecip.nagoya-u.ac.jp,
h_o...@echo.nuee.nagoya-u.ac.jp
WWW homepage http://www.eds.ecip.nagoya-u.ac.jp/~hohta/
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

Inaba Hiroto

unread,
Apr 3, 1998, 3:00:00 AM4/3/98
to

In article <38vhss3...@gaea.ssel.toshiba.co.jp> k...@gaea.ssel.toshiba.co.jp (IRIUCHIJIMA Ken / =?ISO-2022-JP?B?GyRCRn5GYkVnGyhCIBskQjdyGyhC?=) writes:

> >>>>> kazuhik...@toshiba.co.jp (Kazuhiko Nanmei) (="nammei") さん
> >>>>> 2 Apr 1998 10:09:48 GMT に言われるには:

> nammei> mkdirの-pオプション相当を実現したいのですが、どんなふうに
> nammei> 書けば良いんでしょうか?

> ばらして、上から順番にあるかどうか試しながら作っていけばよいですね。


> 区切りが '/' なので若干面倒ですが考え方だけ書くと、$_ に a/b/c/d が入っ
> ているとして

> @d = split m'/';

> for (@d) {
> mkdir $_
> unless -d $_;
> chdir $_;
> }

この考え方でいいと思いますが、ちょっとだけ別のやりかたをしてみました。

#/usr/local/bin/perl -w
for (@ARGV) {
while (m:/|$:g) {
mkdir $`, 0777 or die "Can't mkdir $`: $!\n" if $` ne "" and !-d $`;
}
}

一応このままスクリプトにしても動くようにしたつもりですが、本当に問題ない
とは保証しません:->。

In article <6g063d$475$1...@meshsv66.os.mesh.ad.jp> m-a...@mxa.meshnet.or.jp writes:

> "`"を使ってシェルで実行すればよいわけですから、

> `mkdir -p a/b/c/d`;

さぼるなら、この考え方でいいですが、使うのは

system("mkdir -p a/b/c/d");

の方がよいと思います。
--
稲葉 浩人 (in...@st.rim.or.jp)


IRIUCHIJIMA Ken / 入内島 健

unread,
Apr 6, 1998, 3:00:00 AM4/6/98
to

>>>>> in...@st.rim.or.jp (Inaba Hiroto) (="稲") さん
>>>>> <yaxo1a...@carnival.st.rim.or.jp> で
>>>>> 3 Apr 1998 01:02:49 +0900 に言われるには:

nammei> mkdirの-pオプション相当を実現したいのですが、どんなふうに
nammei> 書けば良いんでしょうか?

...


> @d = split m'/';

> for (@d) {
> mkdir $_
> unless -d $_;
> chdir $_;
> }

稲> この考え方でいいと思いますが、ちょっとだけ別のやりかたをしてみました。

私のやり方は基本に忠実ではあったと思いますが、

稲> #/usr/local/bin/perl -w
稲> for (@ARGV) {
稲> while (m:/|$:g) {
稲> mkdir $`, 0777 or die "Can't mkdir $`: $!\n" if $` ne "" and !-d $`;
稲> }
稲> }

また、目から鱗が落ちました。稲葉さんのコードを見ていると、自分にとって
はまだまだ perl が外国語なのを思い知ります。

m//g を list context で使えば split は使わずに済んでしまうんですね。し
かも、$` を使えばいちいち chdir する必要がない、と。

Kazuhiko Nanmei

unread,
Apr 21, 1998, 3:00:00 AM4/21/98
to

なんめい@東芝です。

大田@名古屋大学 さん
東 さん
稲葉 浩人 さん
入内島 健 さん

回答有難う御座いました。
(以下、読みづらいかもしれませんが・・・)


In article <6fvo5c$j...@ux37.fuchu.toshiba.co.jp>, kazuhik...@toshiba.co.jp says...


>
>実際使うコマンドは、mkdirでは無く、他の外部コマンドなんですが・・・
>また、そのコマンドが、-pの様なオプションを実装してくれていなんで
>困ったしだいです。

というのが、真意です。
質問の内容が伝わらずに、スミマセンでした。


In article <38zphzq...@gaea.ssel.toshiba.co.jp>, k...@gaea.ssel.toshiba.co.jp says...


>
>>>>>> in...@st.rim.or.jp (Inaba Hiroto) (="稲") さん
>>>>>> <yaxo1a...@carnival.st.rim.or.jp> で
>>>>>> 3 Apr 1998 01:02:49 +0900 に言われるには:
>
> nammei> mkdirの-pオプション相当を実現したいのですが、どんなふうに
> nammei> 書けば良いんでしょうか?
>...
>> @d = split m'/';
>
>> for (@d) {
>> mkdir $_
>> unless -d $_;
>> chdir $_;
>> }
>
> 稲> この考え方でいいと思いますが、ちょっとだけ別のやりかたをしてみました。
>
>私のやり方は基本に忠実ではあったと思いますが、
>
> 稲> #/usr/local/bin/perl -w
> 稲> for (@ARGV) {
> 稲> while (m:/|$:g) {
> 稲> mkdir $`, 0777 or die "Can't mkdir $`: $!\n" if $` ne "" and !-d $`;
> 稲> }
> 稲> }
>
>また、目から鱗が落ちました。稲葉さんのコードを見ていると、自分にとって
>はまだまだ perl が外国語なのを思い知ります。
>
>m//g を list context で使えば split は使わずに済んでしまうんですね。し
>かも、$` を使えばいちいち chdir する必要がない、と。
>--


う~ん。(?_?)
私には???(解釈できません)です。(T_T)
修行が足りなくて、ごめんなさいm(__)mです。

健さん のなら、何とか解る気がしますが、
実際にしたい事は、mkdirじゃなくて、他の外部コマンドなので、
system()で実行するとしたら・・・、
そうそう、ディレクトリが既存であるかを確認するのにも、lsコマンド相当のもの
を使うしか手立てが無いんです。(test文?が使えない)

●ディレクトリを作るには・・・
system("MKDIR $_ >/dev/null 2>&1") ; #←「MKDIR」は、/bin/mkdirと同様の振る舞い・・・
MKDIRのリターン値によって「0:成功」「それ以外:失敗」。

●ディレクトリが既存か、確認するには・・・
system("LS -d $_ >/dev/null 2>&1") ; # ←「LS」は、/bin/lsと同様の振る舞い・・・
LSのリターン値によって「0:成功(既存)」「それ以外:失敗(存在しない)」。

という具合です。

私なりに書いてみたのが、以下です。
------------------------------------------------------
#! /usr/local/bin/perl
$path = "" ; パスの初期化

# ↓実用適にはARGVを使うのが良いんですが、サンプルという事で・・・
$_ = '/hoge_top/a/b/c' ;


@d = split m'/';

for (@d) {
$path = join("/", $path , $_ );
$path =~ s#/+#/#g ;
system("MKDIR $path >/dev/null 2>&1") if system("LS -d $path >/dev/null 2>&1") ;
}
------------------------------------------------------

エラーなどについて、一切考慮してないことを除けば、
期待した動きをしてくれています。

それも、全て、助言して下さった皆さんのお陰だと感じています。
本当に有難う御座いました。m(__)m


IRIUCHIJIMA Ken / 入内島 健

unread,
Apr 21, 1998, 3:00:00 AM4/21/98
to

>>>>> kazuhik...@toshiba.co.jp (Kazuhiko Nanmei) (="nammei") さん
>>>>> <6hhk95$f...@ux37.fuchu.toshiba.co.jp> で
>>>>> 21 Apr 1998 08:10:13 GMT に言われるには:

>> 実際使うコマンドは、mkdirでは無く、他の外部コマンドなんですが・・・
>> また、そのコマンドが、-pの様なオプションを実装してくれていなんで
>> 困ったしだいです。

nammei> というのが、真意です。
nammei> 質問の内容が伝わらずに、スミマセンでした。

いえ、-d が使えないことを除けば、わかっていましたよ。ご心配なく。

nammei> 私なりに書いてみたのが、以下です。

ちょっと刈り込んでみました。

nammei> $path = "" ; パスの初期化

これはなくても同じですね。元々空なので。

nammei> $path = join("/", $path , $_ );

これは
$path .= "/$_";

の方が読みやすいでしょう。perl の実装を知らないので、速いかどうかは言
えませんが。

nammei> $path =~ s#/+#/#g ;

@d が split で作ったものなら、この処理が必要になる場合はないのではない
でしょうか?


その他端折って、こんな感じにしてしまいます:

#! /usr/local/bin/perl
for (split m'/', '/hoge_top/a/b/c') {
$path .= "/$_";


system("MKDIR $path >/dev/null 2>&1")
if system("LS -d $path >/dev/null 2>&1");
}

Inaba Hiroto

unread,
Apr 22, 1998, 3:00:00 AM4/22/98
to

Followup-To: fj.comp.lang.perlとしました.

kazuhik...@toshiba.co.jp (Kazuhiko Nanmei) writes:

稲> #/usr/local/bin/perl -w
稲> for (@ARGV) {
稲> while (m:/|$:g) {
稲> mkdir $`, 0777 or die "Can't mkdir $`: $!\n" if $` ne "" and !-d $`;
稲> }
稲> }

> う~ん。(?_?)


> 私には???(解釈できません)です。(T_T)
> 修行が足りなくて、ごめんなさいm(__)mです。

いえいえ, 自分が衒学的なこと書いてしまったんで, あやまるとしたらこっち
です. でも上の意味がわかるくらいにPerlになじんでもらえたら嬉しいです.

一応自分のコードを書きかえると,

$_ = '/hoge_top/a/b/c';


while (m:/|$:g) {

system("MKDIR $` >/dev/null 2>&1") and die "MKDIR failed for $`\n"
if $` ne "" and system("LS -d $` >/dev/null 2>&1") ;
}

です.
--
稲葉 浩人 <in...@sdd.tokyo-sc.toshiba.co.jp/in...@st.rim.or.jp>

IRIUCHIJIMA Ken / 入内島 健

unread,
Apr 22, 1998, 3:00:00 AM4/22/98
to

Followup-To: fj.comp.lang.perl

を忘れてました ^^;

>>>>> 私が 21 Apr 1998 18:51:28 +0900 に書きました:

nammei> $path =~ s#/+#/#g ;

入> @d が split で作ったものなら、この処理が必要になる場合はないのではない
入> でしょうか?

元々 $_ に // がある場合を忘れていました。しかし、先に処理してしまった
方がわかりやすそうです。

#! /usr/local/bin/perl
$_ = '/hoge_top/a/b/c'
s#/+#/#g;
for (split m'/') {


$path .= "/$_";
system("MKDIR $path >/dev/null 2>&1")
if system("LS -d $path >/dev/null 2>&1");
}

になりますね。

t...@imasy.or.jp

unread,
Apr 24, 1998, 3:00:00 AM4/24/98
to

>>>>> "Kazuhiko" == Kazuhiko Nanmei <kazuhik...@toshiba.co.jp> writes:

Kazuhiko> mkdirの-pオプション相当を実現したいのですが、どん
Kazuhiko> なふうに書けば良いんでしょうか?

もうたくさんフォローがあるようですが…

use File::Path;

mkpath('/path/name/to/target/directory', 0, 0755);

が mkdir -p と同じ動作をしてくれます。中身は他の方々が書いたことを
やっているだけですが、せっかくの標準ライブラリなので使ったほうが
いいのではないかと思います。

# 第一引数は作成対象のデイxレクトリの文字列表現の他に、
# それらを含む配列へのリファレンスも受け付けます。

--
T. Yamada <t...@imasy.or.jp> (http://www.imasy.or.jp/~tai/index.html.{ja,en})
PGP fingerprint = 6B 57 1B ED 65 4C 7D AE 57 1B 49 A7 F7 C8 23 46

0 new messages