#文件整理
#题目
编写一个 PowerShell 脚本,把指定目录中的文件按扩展名移动到对应的子目录。例如:
downloads/
├── report.pdf
├── photo.jpg
├── notes.txt
└── archive.zip
整理后:
downloads/
├── pdf/
│ └── report.pdf
├── jpg/
│ └── photo.jpg
├── txt/
│ └── notes.txt
└── zip/
└── archive.zip
#要求
- 接收一个目录路径作为参数,路径不存在时给出错误并退出。
- 只处理当前目录下的文件,不递归处理子目录。
- 子目录名使用小写扩展名,例如
.PDF和.pdf归入同一个pdf目录。 - 没有扩展名的文件放入
noext目录。 - 重复运行脚本不应报错。
#参考实现
organize.ps1
param(
[Parameter(Mandatory)]
[string]$Path
)
if (-not (Test-Path -LiteralPath $Path -PathType Container)) {
Write-Error "目录不存在:$Path"
exit 1
}
$files = Get-ChildItem -LiteralPath $Path -File
foreach ($file in $files) {
$ext = $file.Extension.TrimStart('.').ToLowerInvariant()
if ([string]::IsNullOrEmpty($ext)) {
$ext = 'noext'
}
$destination = Join-Path $Path $ext
if (-not (Test-Path -LiteralPath $destination)) {
New-Item -ItemType Directory -Path $destination | Out-Null
}
Move-Item -LiteralPath $file.FullName -Destination $destination
}
运行:
> ./organize.ps1 -Path ~/Downloads
#讲解
Get-ChildItem -File只返回文件,自动跳过子目录;配合-LiteralPath可以避免路径中的通配符被解释。$file.Extension返回带点的扩展名,例如.pdf;TrimStart('.')去掉点,ToLowerInvariant()统一为小写。[string]::IsNullOrEmpty($ext)判断没有扩展名的情况,目录名用noext。Join-Path负责拼接路径,避免手动处理 Windows 与 Linux 的分隔符差异。Test-Path先判断目标目录是否存在,不存在才用New-Item创建,保证幂等。Move-Item移动文件。如果目标位置已有同名文件,命令会报错;需要覆盖时可以加-Force,但应先确认不会误删数据。
调试时可以先加 -WhatIf 查看将要执行的操作:
> Move-Item -LiteralPath $file.FullName -Destination $destination -WhatIf