iT邦幫忙

0

🗂️ 用批次檔與 PowerShell 自動檢查資料夾是否為空

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250910/20155103pj7Se2vp5m.png

🔍 起心動念

某天整理檔案時,我遇到一個困擾:
D:\許多資料夾各自放許多文件
這個路徑下,有數十個子資料夾,彼此之下又有更深層的結構。
我需要快速判斷這些資料夾裡是不是都有檔案,而不是一個個手動打開。

⚡ 第一階段:PowerShell 檢查

一開始我透過 PowerShell 測試,像這樣:

Get-ChildItem "D:\許多資料夾各自放許多文件" -Directory -Recurse

加上 -Recurse 參數,就能一路檢查到最底層。
如果只想知道空資料夾,可以再搭配 Where-Object 過濾。


需求 指令範例


檢查所有子資料夾 Get-ChildItem ... -Directory -Recurse

列出空的子資料夾 Where-Object { -not (Get-ChildItem $_.FullName -Force) }

判斷是否全部不為空 if ($empty) { ... } else { ... }

這讓我很快就能得到「哪些是空的」的清單。

📦 第二階段:做成批次檔

由於此資料夾要分享給其他朋友
我希望能讓任何人在資料夾裡直接雙擊 .bat 檔案來檢查。
於是我把 PowerShell 指令包進批次檔,讓它以 相對路徑 運作:

  • 自動檢查所有層級的資料夾\
  • 忽略 desktop.iniThumbs.db 這些系統雜檔\
  • 執行後顯示成功(綠字 ✅)或失敗(紅字 ❌)\
  • 結尾 pause,視窗不會自動關掉

範例片段:

@echo off
chcp 65001 >nul
powershell -NoProfile -ExecutionPolicy Bypass ^
 "$all = Get-ChildItem -Directory -Recurse;" ^
 "$empty = @();" ^
 "foreach($d in $all){ $items = Get-ChildItem $d.FullName -Force | Where-Object { $_.Name -notin @('desktop.ini','Thumbs.db') }; if(-not $items){ $empty += $d.FullName } }" ^
 "if($empty){ Write-Host '❌ 有空的資料夾:' -ForegroundColor Red; $empty | ForEach-Object { Write-Host $_ -ForegroundColor Yellow } } else { Write-Host '✅ 所有子資料夾(含最底層)都有內容' -ForegroundColor Green }"
pause

這樣就能透過一鍵操作檢查整個結構。

🎨 第三階段:彩蛋 -- 色塊女孩圖案

寫到後來,我還加了一個小彩蛋:
檢查完成後,用 PowerShell 的 Write-Host -ForegroundColor
在主控台畫出一個用色塊拼出的「女孩像素圖」。

這部分雖然和實用性無關,但讓執行結果更有趣。也算是練習 PowerShell
輸出彩色文字的技巧。

GPT畫得難免跑版,自己調

🤔 過程中的坑

在嘗試過程中,踩過幾個坑:

  • GetRelativePath 無法使用:因為 PowerShell 5
    沒有這個方法,只能改用 Uri.MakeRelativeUri 搭配
    UnescapeDataString。\
  • 字串乘法語法錯誤:PowerShell 不能用 ($b * 6)
    這種寫法,只能用迴圈產生字串。\
  • 中文亂碼:需要在批次檔開頭加 chcp 65001,並在 PowerShell 設定
    UTF-8 輸出。\
  • CMD 括號衝突:在批次檔傳遞 PowerShell 指令時,( )
    容易出錯,最後改用單純 Write-Host 串接。

這些修正讓腳本能穩定執行。

💡 適合詢問 GPT 的 Prompt

如果你想嘗試類似需求,可以這樣問 GPT:

  • 如何用 PowerShell 列出所有空的子資料夾?\
  • 我想要一個 .bat 檔,能遞迴檢查所有子資料夾是否為空,並顯示結果。\
  • 怎麼避免批次檔中文亂碼?\
  • PowerShell 有沒有方法在主控台輸出彩色文字?\
  • 如何在批次檔中用相對路徑處理?

完整範例

@echo off
setlocal
chcp 65001 >nul
pushd "%~dp0"

REM ========= 第一段:檢查子資料夾(相對路徑+中文解碼) =========
powershell -NoProfile -ExecutionPolicy Bypass ^
  "$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new();" ^
  "$ErrorActionPreference = 'SilentlyContinue';" ^
  "$base = (Get-Location).Path;" ^
  "$baseUri = [Uri]($base + '\');" ^
  "function Rel([string]$p){ $u = ([Uri]$baseUri).MakeRelativeUri([Uri]$p).ToString(); [Uri]::UnescapeDataString($u).Replace('/','\') }" ^
  "$skip = @('desktop.ini','Thumbs.db');" ^
  "$all  = Get-ChildItem -Directory -Recurse;" ^
  "$empty = @();" ^
  "foreach($d in $all){" ^
  "  $items = Get-ChildItem -LiteralPath $d.FullName -Force | Where-Object { $_.Name -notin $skip };" ^
  "  if(-not $items){ $empty += (Rel $d.FullName) }" ^
  "}" ^
  "if($empty.Count -gt 0){" ^
  "  Write-Host '❌ 有空的資料夾:' -ForegroundColor Red;" ^
  "  $empty | ForEach-Object { Write-Host ('  ' + $_) -ForegroundColor Yellow };" ^
  "  exit 1" ^
  "} else {" ^
  "  Write-Host '✅ 所有子資料夾(含最底層)都有內容' -ForegroundColor Green;" ^
  "  exit 0" ^
  "}"

set "rc=%ERRORLEVEL%"
echo.
REM ========= 第二段:顯示放大版女孩(有五官) =========
powershell -NoProfile -ExecutionPolicy Bypass ^
  "$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new();" ^
  "Write-Host ''; " ^
  "Write-Host '         ' -NoNewline; Write-Host '███' -ForegroundColor DarkYellow -NoNewline; Write-Host '█████████████' -ForegroundColor DarkYellow -NoNewline; Write-Host '██' -ForegroundColor DarkYellow; " ^
  "Write-Host '        ' -NoNewline; Write-Host '██' -ForegroundColor DarkYellow -NoNewline; Write-Host '████████████████' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor DarkYellow; " ^
  "Write-Host '        ' -NoNewline; Write-Host '██' -ForegroundColor DarkYellow -NoNewline; Write-Host '██' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor Black -NoNewline; Write-Host '██' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor Black -NoNewline; Write-Host '██████' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor DarkYellow; " ^
  "Write-Host '        ' -NoNewline; Write-Host '██' -ForegroundColor DarkYellow -NoNewline; Write-Host '████████████████' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor DarkYellow; " ^
  "Write-Host '        ' -NoNewline; Write-Host '██' -ForegroundColor DarkYellow -NoNewline; Write-Host '██████' -ForegroundColor Yellow -NoNewline; Write-Host '████' -ForegroundColor Red -NoNewline; Write-Host '██████' -ForegroundColor Yellow -NoNewline; Write-Host '██' -ForegroundColor DarkYellow; " ^
  "Write-Host '        ' -NoNewline; Write-Host '████' -ForegroundColor DarkYellow -NoNewline; Write-Host '████████████' -ForegroundColor Yellow -NoNewline; Write-Host '████' -ForegroundColor DarkYellow; " ^
  "Write-Host '          ' -NoNewline; Write-Host '██████████████████' -ForegroundColor DarkMagenta; " ^
  "Write-Host '          ' -NoNewline; Write-Host '███' -ForegroundColor DarkMagenta -NoNewline; Write-Host '████████████' -ForegroundColor Magenta -NoNewline; Write-Host '███' -ForegroundColor DarkMagenta; " ^
  "Write-Host ''; Write-Host '  送可愛女孩照一張' -ForegroundColor Cyan;"


pause
popd
REM 不要在這裡 exit,避免視窗關掉

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言