2012年7月8日日曜日

[PowerShell] 沢山のフォルダを自動で作ってくれるロボットできたよー\(^o^)/

沢山のフォルダを自動で作ってくれるPowerShell
「autoCreateFolders.ps1」書きました。
使い方は簡単。
1.まずこんな感じの「FolderList.txt」を作成します。

これは、フォルダツリーをタブで表したものです。
このファイルをインプットとして、このフォルダ構成の通りにフォルダを作成してくれます。

2.沢山のフォルダを作りたい場所に、ps1のファイルとFolderList.txtを置きます。

3.次に、PowerShellを起動します。実行権限はゆるくしておいてくださいね。


4.PowerShellのウィンドウにps1ファイルをドラッグ・アンド・ドロップしてEnterで実行します。

5.以下のように表示されれば成功です。フォルダができてるか確認してください。



4人のフォルダができています。


ちゃんとあのこの彼氏は三人目までいますね。


おかあさんの晩御飯も急遽炊込み御飯になっています。



もちろんお父さんに下町のナポレオンはありません。
かわいそうですね。


以下がプログラムです。
ちゃんと動くようになったので今日は黒霧島を飲もうと思います。
頑張った自分へのご褒美()


#-----------------------------------------------------------
# Author     :TearTheSky(てあざすかい)
# ProgramName:autoCreateFolders
# Discription:「FolderLists.txt」にかかれてあるフォルダ構成
#             の通りにフォルダを自動で作成します。
#-----------------------------------------------------------
#FolderLists.txtは定数として定義するので変更可能です
set-variable -name FolderLists -value "FolderLists.txt" -option constant

#-----------------------------------------------------------
# フォルダ作成関数
#-----------------------------------------------------------
Function Create-Folder( $folderName )
{
 if(Test-Path $folderName) {
 }
 else {
  $currentDirectory = Get-Location
  $createLocation = "$currentDirectory\$folderName"
  [void]$result = New-Item -type directory $createLocation
 }
}

#-----------------------------------------------------------
# 本編
#-----------------------------------------------------------
#このファイルがいる場所へカレントディレクトリを移動
$FilesPath = Split-Path $myInvocation.MyCommand.path
Set-Location $FilesPath

#FolderLists.txtの存在確認
$resultCheckFileExist = Test-Path -path $FolderLists
if($resultCheckFileExist -eq $false) {
 #いない場合は怒って終了
 Write-Host "そんなファイルは存在しません!"
 return
}
else {
 #存在する場合はファイルを読み込み
 $Input = Get-Content ".\$FolderLists" 
 #現在いる場所を示す変数$currentPath
 $currentPath = $filesPath 
 #このファイルがある場所を階層0とした時の
 #今いるフォルダ階層を示す変数$nowDepth
 $nowDepth = 0
 
 #配列の要素を追加する場合は += 演算子を利用しなければならない
 $lastPlace = @()
 $lastPlace += Get-Location | ForEach-Object{$_.Path}

 #$Inuputはテキストファイルそのものなのでそれを1行ずつ処理する
 ForEach($aLine in $Input) {
  #読み込んだ1行にかかれてあるフォルダ名でフォルダを
  #作成すべき階層を示す変数$depth
  $depth = 0
  #階層ごとの最後にいた場所を示す配列変数$lastPlace
  $lastPlace[$nowDepth] = Get-Location | ForEach-Object{$_.Path}
  
  #先頭のタブの数を確認し、それを階層とする
  for($index = 0; $aLine[$index] -eq "`t"; $index++) {
   $depth++
  }
  #----------------------------------
  #現在の階層との比較
  #----------------------------------
  #同じ階層の場合
  if($depth - $nowDepth -eq 0) {
   #タブ文字を取っ払う
   $createName = $aLine.SubString($depth)
   #フォルダをつくるよ!
   Create-Folder($createName)
   #作ったフォルダを次行くべきフォルダに設定
   $nextPath = $currentPath + "\" + $createName
  }
  #1つ下の階層の場合
  elseif($depth - $nowDepth -eq 1) {
   #次行くべきフォルダへ移動する
   Set-Location -path $nextPath
   #移動したので現在のフォルダパスとして今いる場所を設定
   $currentPath = Get-Location | ForEach-Object{$_.Path}
   #1つ下の階層に移動したはずなので階層をインクリメント
   $nowDepth++
   #タブ文字を取っ払う
   $createName = $aLine.SubString($depth)
   #フォルダをつくるよ!
   Create-Folder($createName)
   #次行くべき場所を設定(さっき作ったフォルダ)
   $nextPath = $currentPath + "\" + $createName
   #ここにいたことを$lastPlaceに記録する
   $lastPlace += Get-Location | ForEach-Object{$_.Path}
  }
  #階層が今いる場所より上だった場合(階層を戻る)
  elseif($depth - $nowDepth -lt 0) {
   #戻るべき場所へ戻る。戻ったら…
   Set-Location $lastPlace[$nowDepth - ($nowDepth - $depth)]
   #タブ文字を取っ払う
   $createName = $aLine.SubString($depth)
   #フォルダをつくるよ!
   Create-Folder($createName)
   #現在いる場所の階層数を$nowDepthに設定
   $nowDepth = $nowDepth - ($nowDepth - $depth)
   #移動したので現在のフォルダパスとして今いる場所を設定
   $currentPath = Get-Location | ForEach-Object{$_.Path}
   #次行くべき場所を設定(さっき作ったフォルダ)
   $nextPath = $currentPath + "\" + $createName
   #ここにいたことを$lastPlaceに記録する
   $lastPlace[$nowDepth] = Get-Location | ForEach-Object{$_.Path}
  }
  #どれにも当てはまらない場合
  else {
  #エラーメッセージを出力してスキップ
  write-host "フォルダ名:" + $aLine
  write-host "フォルダが作成できませんでした。階層指定が正しくない可能性があります。"
  Get-Location
  }
 }
 #最後にこのファイルがある場所へ戻って終了
 Set-Location $FilesPath
}

乙 いいちこフラスコボトル 麦30° 720ML
最近いいちこすごっくオシャレですよね。広告とか。
実はまだ飲んだことがない。
今度買ってみようかな。



:2012/07/09 追記;
・定義ファイルの説明を追記
・プログラムの一部を修正
定義ファイル「FolderLists.txt」が存在しない場合の出力が
Out-Stringでは正常に動作しない。
ので、Write-Hostを利用するよう修正



0 件のコメント:

コメントを投稿