PowerShell Remove-Item 静默不删除单个文件
PowerShell Remove-Item silently doesn't remove a single file
我混合了一个 PowerShell 脚本,该脚本以递归方式浏览文件夹以搜索分辨率过低的图片。
我在谷歌上搜索了几个小时的解决方案,但到目前为止我还没有设法删除这些图像。那么这有什么关系呢?
原来是文件名中的方括号导致了问题。但是现在 Remove-Item 抱怨文件被另一个进程使用,我认为是这个脚本本身。
$kuveja = 0
$pikkusii = 0
[void][reflection.assembly]::loadwithpartialname("system.drawing")
function Get-Image{
process {
$file = $_
[Drawing.Image]::FromFile($_.FullName) |
ForEach-Object{
$_ | Add-Member -PassThru NoteProperty FullName ('{0}' -f $file.FullName)
}
}
}
$path = 'H:\Juttui\'
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
$kuva = $_ | Get-Image
if($kuva.Width -lt 960 -and $kuva.Height -lt 960){
Write-Host $_.FullName -fore red
Remove-Item $_.FullName -Force
$pikkusii++
}
elseif($kuva.Width -lt 540 -or $kuva.Height -lt 540){
Write-Host $_.FullName -fore yellow
Remove-Item $_.FullName -Force
$pikkusii++
}
$kuveja++
}
Write-Host "Pics browsed: $kuveja" -fore green
Write-Host "Small: $pikkusii" -fore green
请理解,我是 PowerShell 的完全菜鸟,我不知道还有什么地方比这里更好。
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
# ...
}
?
的意思是Where-Object
,但我觉得你真正想要的是ForEach-Object
。 ForEach-Object
的别名是 %
,但出于这个原因,您不应该在脚本中使用别名(不太清楚)。
试试这个:
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ForEach-Object {
# ...
}
如果这不起作用,您在删除之前有 Write-Host
个调用,那么您是否看到指示删除应该发生的红色和黄色文本?您应该尝试在 ISE 中 运行 您的脚本。在 Remove-Item
调用之前设置一个断点,然后单步执行代码。
我认为您的 $kuva
引用使文件保持打开状态。在尝试删除对象之前尝试执行 .Dispose()
方法。所以像这样:
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
$kuva = $_ | Get-Image
if($kuva.Width -lt 960 -and $kuva.Height -lt 960){
Write-Host $_.FullName -fore red
$kuva.dispose()
Remove-Item $_.FullName -Force
$pikkusii++
}
elseif($kuva.Width -lt 540 -or $kuva.Height -lt 540){
Write-Host $_.FullName -fore yellow
$kuva.dispose()
Remove-Item $_.FullName -Force
$pikkusii++
}
$kuveja++
}
我混合了一个 PowerShell 脚本,该脚本以递归方式浏览文件夹以搜索分辨率过低的图片。
我在谷歌上搜索了几个小时的解决方案,但到目前为止我还没有设法删除这些图像。那么这有什么关系呢?
原来是文件名中的方括号导致了问题。但是现在 Remove-Item 抱怨文件被另一个进程使用,我认为是这个脚本本身。
$kuveja = 0
$pikkusii = 0
[void][reflection.assembly]::loadwithpartialname("system.drawing")
function Get-Image{
process {
$file = $_
[Drawing.Image]::FromFile($_.FullName) |
ForEach-Object{
$_ | Add-Member -PassThru NoteProperty FullName ('{0}' -f $file.FullName)
}
}
}
$path = 'H:\Juttui\'
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
$kuva = $_ | Get-Image
if($kuva.Width -lt 960 -and $kuva.Height -lt 960){
Write-Host $_.FullName -fore red
Remove-Item $_.FullName -Force
$pikkusii++
}
elseif($kuva.Width -lt 540 -or $kuva.Height -lt 540){
Write-Host $_.FullName -fore yellow
Remove-Item $_.FullName -Force
$pikkusii++
}
$kuveja++
}
Write-Host "Pics browsed: $kuveja" -fore green
Write-Host "Small: $pikkusii" -fore green
请理解,我是 PowerShell 的完全菜鸟,我不知道还有什么地方比这里更好。
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
# ...
}
?
的意思是Where-Object
,但我觉得你真正想要的是ForEach-Object
。 ForEach-Object
的别名是 %
,但出于这个原因,您不应该在脚本中使用别名(不太清楚)。
试试这个:
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ForEach-Object {
# ...
}
如果这不起作用,您在删除之前有 Write-Host
个调用,那么您是否看到指示删除应该发生的红色和黄色文本?您应该尝试在 ISE 中 运行 您的脚本。在 Remove-Item
调用之前设置一个断点,然后单步执行代码。
我认为您的 $kuva
引用使文件保持打开状态。在尝试删除对象之前尝试执行 .Dispose()
方法。所以像这样:
Get-ChildItem $path\* -Include *.jpg, *.jpeg* -Recurse | ? {
$kuva = $_ | Get-Image
if($kuva.Width -lt 960 -and $kuva.Height -lt 960){
Write-Host $_.FullName -fore red
$kuva.dispose()
Remove-Item $_.FullName -Force
$pikkusii++
}
elseif($kuva.Width -lt 540 -or $kuva.Height -lt 540){
Write-Host $_.FullName -fore yellow
$kuva.dispose()
Remove-Item $_.FullName -Force
$pikkusii++
}
$kuveja++
}