按照排序顺序获取子项,然后根据提示输入进行删除。

huangapple go评论85阅读模式
英文:

Get-childitem sorted and then delete upon promt input

问题

以下是您要翻译的内容:

  1. "i try to sort a list and give it over as variable to then do something with the list. when i run the code without $files (the variable) then it list perfect. when i set the $files in front the output is nothing. what am i doing wrong ? i am very new to powershell and tried since hours to find the right combination, but i seem to not see thru."

    我尝试对列表进行排序并将其作为变量传递,然后对列表执行某些操作。当我在不使用$files(变量)的情况下运行代码时,它能够正常列出。但当我在前面设置了$files时,输出为空。我做错了什么?我是PowerShell的新手,已经尝试了几个小时,但似乎无法找到正确的组合。

  2. "this code below sorts exactly as wanted, but then delete is not working because $files is nowhere defined i think"

    下面的这段代码按照所需的方式排序,但删除操作不起作用,因为我认为$files没有被定义。

  3. "i tried this code, but does not even do get-childitem list"

    我尝试了这段代码,但甚至没有列出get-childitem的列表。

英文:

i try to sort a list and give it over as variable to then do something with the list. when i run the code without $files (the variable) then it list perfect. when i set the $files in front the output is nothing. what am i doing wrong ? i am very new to powershell and tried since hours to find the right combination, but i seem to not see thru.

this code below sorts exactly as wanted, but then delete is not working because $files is nowhere defined i think

  1. do {
  2. Get-childitem -Path E:\TestEnv\deleted_images\ -recurse -include @("Image*") | Sort-Object -Property LastAccessTime
  3. Group-Object Name -AsHashTable
  4. $files.Values
  5. $userinput = Read-Host -Prompt 'Please Enter Folder name to be deleted'
  6. if ($files.ContainsKey($userinput)) {
  7. $files[$userinput] | Remove-item
  8. Write-Host 'Folder was deleted'
  9. }
  10. }
  11. until([string]::IsNullOrWhiteSpace($userinput))

按照排序顺序获取子项,然后根据提示输入进行删除。

i tried this code, but does not even do get-childitem list

  1. do {
  2. $files = Get-childitem -Path E:\TestEnv\deleted_images\ -recurse -include @("Image*") | Sort-Object -Property LastAccessTime
  3. Group-Object Name -AsHashTable
  4. $files.Values
  5. $userinput = Read-Host -Prompt 'Please Enter Folder name to be deleted'
  6. if ($files.ContainsKey($userinput)) {
  7. $files[$userinput] | Remove-item
  8. Write-Host 'Folder was deleted'
  9. }
  10. }
  11. until([string]::IsNullOrWhiteSpace($userinput))

按照排序顺序获取子项,然后根据提示输入进行删除。

答案1

得分: 1

这是修改后的代码,我用来首先将图像文件夹移动到删除文件夹。

  1. function Do-Menu {
  2. [CmdletBinding()]
  3. param (
  4. [string]$Path = $PWD, # 默认为当前工作目录
  5. [string]$Filter = 'Image*',
  6. [string]$Title = '请选择要移动的文件夹'
  7. )
  8. cls
  9. # 如果您只想匹配单个通配符字符串的名称,请使用 Filter,而不是 Include
  10. $dirs = @(Get-ChildItem -Path $Path -Filter $Filter -Recurse -Directory) | Sort-Object LastWriteTime
  11. # 仅在找到具有该名称的目录时继续
  12. if (!$dirs.Count) {
  13. Write-Host "没有找到与筛选器 '$Filter' 匹配的目录..."
  14. return $false # 以 False 值退出函数
  15. }
  16. # 创建菜单
  17. if (![string]::IsNullOrWhiteSpace($Title)) {
  18. $dashLine = '-' * ($Title -split '\r?\n' | Measure-Object -Maximum -Property Length).Maximum
  19. Write-Host "$Title`r`n$dashLine`r`n" -ForegroundColor Yellow
  20. }
  21. $index = 1
  22. $dirs | ForEach-Object {
  23. # 写出菜单项
  24. $align = $dirs.Count.ToString().Length
  25. # {0,$align} 将索引号对齐到右侧
  26. # 有关更多 DateTime 格式,请参见链接
  27. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
  28. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
  29. Write-Host ("{0,$align}. {1:yyyy-MM-dd HH:mm:ss} {2}" -f $index++, $_.LastWriteTime, $_.FullName)
  30. }
  31. # 现在要求用户输入
  32. $message = "`r`n请输入要删除的目录的索引号.`r`n"
  33. if ($dirs.Count -gt 1) { $message += "要选择多个项目,请使用逗号分隔数字.`r`n" }
  34. Write-Host $message -ForegroundColor Yellow
  35. $selection = Read-Host
  36. # 确保输入完全是数字,不包含 '0' 值,或高于目录数量的值
  37. $selection = [int[]]($selection -replace '[^\d,]' -split ',' |
  38. Where-Object { $_ -match '\d+' -and ([int]$_ -gt 0 -and [int]$_ -le $dirs.Count)})
  39. if (!$selection.Count) { return $false } # 空输入时退出
  40. # 遍历选定的索引并删除匹配的文件夹
  41. $selection | ForEach-Object {
  42. $folder = $dirs[$_ - 1]
  43. # 确保您不试图删除刚刚删除父文件夹的文件夹
  44. if (Test-Path -Path $folder.FullName -PathType Container) {
  45. $folder | Move-Item -Destination $targetdir
  46. Write-Host "文件夹 $($folder.FullName) 已被移动"
  47. }
  48. }
  49. # 在短暂暂停后返回 True 以重新构建菜单
  50. Start-Sleep 4
  51. $true
  52. }
  53. # 主代码
  54. $path = 'E:\TestEnv\Repository\images'
  55. $targetdir = 'E:\TestEnv\deleted_images'
  56. while ($true) {
  57. $result = Do-Menu -Path $path
  58. # 如果用户取消或没有与筛选器匹配的文件夹,则退出循环
  59. if (!$result) { break }
  60. }
  61. cls
  62. Write-Host "`r`n操作完成!" -ForegroundColor Green

这是修改后的代码,用于将图像文件夹移动到删除文件夹。

英文:

here is the modified code which i use to first move the image folders to the delete folder.

  1. function Do-Menu {
  2. [CmdletBinding()]
  3. param (
  4. [string]$Path = $PWD, # default to current working directory
  5. [string]$Filter = 'Image*',
  6. [string]$Title = 'Please select the folder(s) to move'
  7. )
  8. cls
  9. # if you only want to match the name on a single wildcard string, use Filter, not Include
  10. $dirs = @(Get-childitem -Path $Path -Filter $Filter -Recurse -Directory) | Sort-Object LastWriteTime
  11. # only proceed if there are directories found by that name
  12. if (!$dirs.Count) {
  13. Write-Host "No directories found that match filter '$Filter'.."
  14. return $false # exit the function with a value of False
  15. }
  16. # create the menu
  17. if (![string]::IsNullOrWhiteSpace($Title)) {
  18. $dashLine = '-' * ($Title -split '\r?\n' | Measure-Object -Maximum -Property Length).Maximum
  19. Write-Host "$Title`r`n$dashLine`r`n" -ForegroundColor Yellow
  20. }
  21. $index = 1
  22. $dirs | ForEach-Object {
  23. # write out the menu items
  24. $align = $dirs.Count.ToString().Length
  25. # {0,$align} aligns the index number to the right
  26. # for more DateTime formats see
  27. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
  28. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
  29. Write-Host ("{0,$align}. {1:yyyy-MM-dd HH:mm:ss} {2}" -f $index++, $_.LastWriteTime, $_.FullName)
  30. }
  31. # now ask for user input
  32. $message = "`r`nType the index number of the directory you wish to delete.`r`n"
  33. if ($dirs.Count -gt 1) { $message += "To select multiple items, separate the numbers with commas.`r`n" }
  34. Write-Host $message -ForegroundColor Yellow
  35. $selection = Read-Host
  36. # make sure the input is all numeric and contains no '0' values
  37. # or values higher than the number of directories
  38. $selection = [int[]]($selection -replace '[^\d,]' -split ',' |
  39. Where-Object { $_ -match '\d+' -and ([int]$_ -gt 0 -and [int]$_ -le $dirs.Count)})
  40. if (!$selection.Count) { return $false } # exit on empty input
  41. # loop over the selected indices and delete the matching folders
  42. $selection | ForEach-Object {
  43. $folder = $dirs[$_ - 1]
  44. # make sure you are not trying to remove a folder of which the parent
  45. # folder has just been removed
  46. if (Test-Path -Path $folder.FullName -PathType Container) {
  47. $folder | Move-Item -Destination $targetdir
  48. Write-Host "Folder $($folder.FullName) has been moved"
  49. }
  50. }
  51. # return True to have the menu rebuilt after a short pause
  52. Start-Sleep 4
  53. $true
  54. }
  55. # main code
  56. $path = 'E:\TestEnv\Repository\images'
  57. $targetdir = 'E:\TestEnv\deleted_images'
  58. while ($true) {
  59. $result = Do-Menu -Path $path
  60. # if the user cancelled, or if there were no folders matching the filter, exit the while loop
  61. if (!$result) { break }
  62. }
  63. cls
  64. Write-Host "`r`nAll done!" -ForegroundColor Green

答案2

得分: 0

不要有别的内容,只返回翻译好的部分:

  1. 而不是使用 `Read-Host`用户可以输入几乎任何内容...),我会使用 `Out-GridView`正如 [Keith Miller](https://stackoverflow.com/questions/75953342/get-childitem-sorted-and-then-delete-upon-promt-input?noredirect=1#comment133968511_75953342) 已经建议的那样。
  2. 这将为用户提供一个图形化的目录列表使选择一个或多个目录更容易删除
  3. ```powershell
  4. $path = 'E:\TestEnv\deleted_images'
  5. # 进入一个无限循环。如果用户单击“取消”按钮或没有找到与 Filter 中的名称匹配的目录,我们将退出循环
  6. while ($true) {
  7. # 如果您只想匹配单个通配符字符串的名称,请使用 Filter,而不是 Include
  8. $dirs = Get-childitem -Path $path -Filter 'Image*' -Recurse -Directory | Sort-Object LastAccessTime
  9. # 仅在找到该名称的目录时继续
  10. if (@($dirs).Count) {
  11. $selection = $dirs | Out-GridView -Title '请选择要删除的文件夹' -PassThru
  12. # 如果用户取消,退出循环
  13. if (!$selection) { break }
  14. # 用户可能选择了多个目录,因此使用循环
  15. $selection | ForEach-Object {
  16. $_ | Remove-Item -Recurse
  17. Write-Host "文件夹 $($_.FullName) 已删除"
  18. }
  19. }
  20. else {
  21. Write-Host "未找到与筛选条件匹配的目录..."
  22. break # 未找到该名称的目录,因此退出循环
  23. }
  24. }
  25. Write-Host "全部完成" -ForegroundColor Green

根据您的评论,您无法使用图形化的 Out-GridView,以下是使用控制台菜单的方法。

  1. function Do-Menu {
  2. [CmdletBinding()]
  3. param (
  4. [string]$Path = $PWD, # 默认为当前工作目录
  5. [string]$Filter = 'Image*',
  6. [string]$Title = '请选择要删除的文件夹'
  7. )
  8. cls
  9. # 如果您只想匹配单个通配符字符串的名称,请使用 Filter,而不是 Include
  10. $dirs = @(Get-childitem -Path $Path -Filter $Filter -Recurse -Directory) | Sort-Object LastWriteTime
  11. # 仅在找到该名称的目录时继续
  12. if (!$dirs.Count) {
  13. Write-Host "未找到与筛选条件 '$Filter' 匹配的目录..."
  14. return $false # 返回值为 False 退出函数
  15. }
  16. # 创建菜单
  17. if (![string]::IsNullOrWhiteSpace($Title)) {
  18. $dashLine = '-' * ($Title -split '\r?\n' | Measure-Object -Maximum -Property Length).Maximum
  19. Write-Host "$Title`r`n$dashLine`r`n" -ForegroundColor Yellow
  20. }
  21. $index = 1
  22. $dirs | ForEach-Object {
  23. # 输出菜单项
  24. $align = $dirs.Count.ToString().Length
  25. # {0,$align} 将索引号右对齐
  26. # 有关更多日期时间格式,请参见链接
  27. Write-Host ("{0,$align}. {1:yyyy-MM-dd HH:mm:ss} {2}" -f $index++, $_.LastWriteTime, $_.FullName)
  28. }
  29. # 现在请用户输入
  30. $message = "`r`n请输入您要删除的目录的索引号。`r`n"
  31. if ($dirs.Count -gt 1) { $message += "要选择多个项目,请用逗号分隔这些数字。`r`n" }
  32. Write-Host $message -ForegroundColor Yellow
  33. $selection = Read-Host
  34. # 确保输入全为数字,不包含 '0' 值,且不大于目录数量
  35. $selection = [int[]]($selection -replace '[^\d,]' -split ',' |
  36. Where-Object { $_ -match '\d+' -and ([int]$_ -gt 0 -and [int]$_ -le $dirs.Count)})
  37. if (!$selection.Count) { return $false } # 输入为空时退出
  38. # 循环遍历所选的索引并删除匹配的文件夹
  39. $selection | ForEach-Object {
  40. $folder = $dirs[$_ - 1]
  41. # 确保您不尝试删除刚刚删除父文件夹的文件夹
  42. if (Test-Path -Path $folder.FullName -PathType Container) {
  43. $folder | Remove-Item -Recurse
  44. Write-Host "文件夹 $($folder.FullName) 已删除"
  45. }
  46. }
  47. # 返回 True 以在短暂的暂停后重建菜单
  48. Start-Sleep 4
  49. $true
  50. }
  51. # 主代码
  52. $path = 'E:\TestEnv\deleted_images'
  53. while ($true) {
  54. $result = Do-Menu -Path $path
  55. # 如果用户取消,或者没有与筛选条件匹配的文件夹,退出循环
  56. if (!$result) { break }
  57. }
  58. cls
  59. Write-Host "`r`n全部完成!" -ForegroundColor Green
英文:

Instead of using Read-Host (where a user can type in just about anything..), I would use Out-GridView as Keith Miller already suggested.

This will provide a graphical list of directories to the user making it much easier to select one or more directories to delete.

  1. $path = 'E:\TestEnv\deleted_images'
  2. # enter an endless loop. We'll break out if the user clicks the Cancel button
  3. # or when there are no directories found that match the name in the Filter
  4. while ($true) {
  5. # if you only want to match the name on a single wildcard string, use Filter, not Include
  6. $dirs = Get-childitem -Path $path -Filter 'Image*' -Recurse -Directory | Sort-Object LastAccessTime
  7. # only proceed if there are directories found by that name
  8. if (@($dirs).Count) {
  9. $selection = $dirs | Out-GridView -Title 'Please select the folder(s) to delete' -PassThru
  10. # if the user cancelled, exit the while loop
  11. if (!$selection) { break }
  12. # the user could have selected more than one directory, so use a loop
  13. $selection | ForEach-Object {
  14. $_ | Remove-Item -Recurse
  15. Write-Host "Folder $($_.FullName) has been deleted"
  16. }
  17. }
  18. else {
  19. Write-Host "No directories found that match the filter.."
  20. break # no directory by that name found, so exit the while loop
  21. }
  22. }
  23. Write-Host "All done" -ForegroundColor Green

<hr>

As per your comment you cannot use the graphical Out-GridView, here's the idea using a console menu.

  1. function Do-Menu {
  2. [CmdletBinding()]
  3. param (
  4. [string]$Path = $PWD, # default to current working directory
  5. [string]$Filter = &#39;Image*&#39;,
  6. [string]$Title = &#39;Please select the folder(s) to delete&#39;
  7. )
  8. cls
  9. # if you only want to match the name on a single wildcard string, use Filter, not Include
  10. $dirs = @(Get-childitem -Path $Path -Filter $Filter -Recurse -Directory) | Sort-Object LastWriteTime
  11. # only proceed if there are directories found by that name
  12. if (!$dirs.Count) {
  13. Write-Host &quot;No directories found that match filter &#39;$Filter&#39;..&quot;
  14. return $false # exit the function with a value of False
  15. }
  16. # create the menu
  17. if (![string]::IsNullOrWhiteSpace($Title)) {
  18. $dashLine = &#39;-&#39; * ($Title -split &#39;\r?\n&#39; | Measure-Object -Maximum -Property Length).Maximum
  19. Write-Host &quot;$Title`r`n$dashLine`r`n&quot; -ForegroundColor Yellow
  20. }
  21. $index = 1
  22. $dirs | ForEach-Object {
  23. # write out the menu items
  24. $align = $dirs.Count.ToString().Length
  25. # {0,$align} aligns the index number to the right
  26. # for more DateTime formats see
  27. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
  28. # https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
  29. Write-Host (&quot;{0,$align}. {1:yyyy-MM-dd HH:mm:ss} {2}&quot; -f $index++, $_.LastWriteTime, $_.FullName)
  30. }
  31. # now ask for user input
  32. $message = &quot;`r`nType the index number of the directory you wish to delete.`r`n&quot;
  33. if ($dirs.Count -gt 1) { $message += &quot;To select multiple items, separate the numbers with commas.`r`n&quot; }
  34. Write-Host $message -ForegroundColor Yellow
  35. $selection = Read-Host
  36. # make sure the input is all numeric and contains no &#39;0&#39; values
  37. # or values higher than the number of directories
  38. $selection = [int[]]($selection -replace &#39;[^\d,]&#39; -split &#39;,&#39; |
  39. Where-Object { $_ -match &#39;\d+&#39; -and ([int]$_ -gt 0 -and [int]$_ -le $dirs.Count)})
  40. if (!$selection.Count) { return $false } # exit on empty input
  41. # loop over the selected indices and delete the matching folders
  42. $selection | ForEach-Object {
  43. $folder = $dirs[$_ - 1]
  44. # make sure you are not trying to remove a folder of which the parent
  45. # folder has just been removed
  46. if (Test-Path -Path $folder.FullName -PathType Container) {
  47. $folder | Remove-Item -Recurse
  48. Write-Host &quot;Folder $($folder.FullName) has been deleted&quot;
  49. }
  50. }
  51. # return True to have the menu rebuilt after a short pause
  52. Start-Sleep 4
  53. $true
  54. }
  55. # main code
  56. $path = &#39;E:\TestEnv\deleted_images&#39;
  57. while ($true) {
  58. $result = Do-Menu -Path $path
  59. # if the user cancelled, or if there were no folders matching the filter, exit the while loop
  60. if (!$result) { break }
  61. }
  62. cls
  63. Write-Host &quot;`r`nAll done!&quot; -ForegroundColor Green

huangapple
  • 本文由 发表于 2023年4月7日 04:03:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定