PowerShell实现文件夹筛选、字符串匹配及TimeSpan时间转换的技术求助
Let’s break down your requirements step by step—filtering folders that match a specific string pattern, then using TimeSpan to extract days, hours, and minutes from their timestamp properties.
Step 1: Filter Folders with String Matching (Using ForEach-Object)
Your existing command already retrieves folders starting with K, but we can enhance it with targeted string matching and process each item via PowerShell’s pipeline-based ForEach-Object.
For example, if you want to filter folders whose name contains "BK", add a Where-Object clause to narrow down results before processing:
cls Get-ChildItem -Path '.\k*' -Recurse -Directory | Where-Object { $_.Name -match "BK" } | # Match folders with "BK" in their name Sort-Object -Property Name -Descending | ForEach-Object { # Capture folder details $folderName = $_.Name $creationTime = $_.CreationTime $lastWriteTime = $_.LastWriteTime # Calculate time elapsed since last modification (vs current time) $timeElapsed = (Get-Date) - $lastWriteTime # Extract days, hours, minutes directly from the TimeSpan object $days = $timeElapsed.Days $hours = $timeElapsed.Hours $minutes = $timeElapsed.Minutes # Output structured results [PSCustomObject]@{ FolderName = $folderName CreationTime = $creationTime LastWriteTime = $lastWriteTime DaysElapsed = $days HoursElapsed = $hours MinutesElapsed = $minutes } } | Format-Table -AutoSize
String Matching Options:
- Use
-match "BK"for regex-based matching (finds "BK" anywhere in the name). For exact matches, use-eq "ExactFolderName". - PowerShell’s matching is case-insensitive by default; use
-cmatchif you need case-sensitive regex matching.
Step 2: Correct TimeSpan Handling
Your initial TimeSpan code had syntax errors (missing parentheses, incorrect variable assignments). The example above shows the proper approach:
- Subtract two datetime values (e.g.,
(Get-Date) - $lastWriteTime) to get aTimeSpanobject directly. - The
TimeSpanobject has built-in properties likeDays,Hours, andMinutes—no need for manual truncation withMath::Truncate!
If you need to convert a raw decimal value (like total hours as a decimal) into a TimeSpan, use this method:
$totalHours = 123.75 # Example: 123 full hours + 45 minutes $timeSpan = [TimeSpan]::FromHours($totalHours) Write-Host "Days: $($timeSpan.Days), Hours: $($timeSpan.Hours), Minutes: $($timeSpan.Minutes)"
Step 3: Alternative: Traditional foreach Loop
If you prefer a non-pipeline foreach loop instead of ForEach-Object, here’s how to structure it:
cls # First, collect and filter the folders $folders = Get-ChildItem -Path '.\k*' -Recurse -Directory | Where-Object { $_.Name -match "BK" } | Sort-Object -Property Name -Descending # Process each folder in a loop foreach ($folder in $folders) { $timeElapsed = (Get-Date) - $folder.LastWriteTime [PSCustomObject]@{ FolderName = $folder.Name CreationTime = $folder.CreationTime LastWriteTime = $folder.LastWriteTime DaysElapsed = $timeElapsed.Days HoursElapsed = $timeElapsed.Hours MinutesElapsed = $timeElapsed.Minutes } } | Format-Table -AutoSize
Key Notes:
- Use
[PSCustomObject]to create structured output that’s easy to read, sort, or export (e.g., to CSV withExport-Csv). - If you need cumulative decimal values (like total days including hours/minutes), use
TotalDays,TotalHours, orTotalMinutesproperties of theTimeSpanobject.
内容的提问来源于stack exchange,提问作者Arenas

