Powershell:删除每n个文件

时间:2016-05-26 02:00:53

标签: loops powershell delete-file

我刚刚导入了一堆图片,并意识到每张图片有3个副本,但它们按顺序命名。

基本上这三个文件是相同的:

P5240901.dng
P5240902.dng
P5240903.dng

那就是大约1600张照片。

我正在研究编写一个简单的PowerShell脚本(我使用Windows)来查看这些文件的目录,并保留1个文件,只需循环浏览一系列文件。 我没有找到能够解决这个问题的事情。我文件前的字符,我不熟悉PowerShell语言。

有什么想法吗? 谢谢!

2 个答案:

答案 0 :(得分:0)

尝试以下操作,只保留名称相同的文件组中的第一个文件,除了文件扩展名之前的最后一个字符,假设该字符是一个数字(语法假定为PSv3 +):

'P5240901.dng', 'P5240902.dng', 'P5240903.dng', 'A1.dng', 'A2.dng', 'singleton.dng' | 
  Group-Object { $_ -replace '^(.+)\d\.', '$1' } | 
   ? Count -gt 1 |
     % { $_.Group[1..$($_.Group.Count)] }

的产率:

P5240902.dng
P5240903.dng
A2.dng

通过调用Get-ChildItem -File替换示例输入数组,并将Remove-Item添加到$_.Group[1..$($_.Group.Count)]以执行实际删除。

以上命令使用带有输入文件名字符串数组,但[System.IO.FileInfo]输出的Get-ChildItem实例将有效地执行在字符串上下文中相同:它们将扩展为各自的文件名。

这个解决方案的优点是它不依赖于严格按3组出现的输入文件:

  • 除了文件扩展名前至少有2个成员(除此之外的任何数字)之外的任何一个共享相同名称的输入文件组将包含每个成员但第一个被删除。
  • 任何其他文件都保持不变。

<强>解释

  • Group-Object { $_ -replace '^(.+)\d\.', '$1' }

    • 通过它们共享的文件名部分有效地对输入文件进行分组(但只有在文件扩展名之前它们共享除了最后一个字符之外的所有内容时,如果该字符是一个数字)。
  • ? Count -gt 1

    • 仅传递至少有2个成员的结果组。
  • % { $_.Group[1..$($_.Group.Count)] }

    • 处理每个组的文件,但第1个文件除外。

更新:这是OP后来评论提示的变体: 在给定输入文件名(如P5240901.dng, P5240902.dng, ..., P5240910.dng, P5240911.dng, ..., P5240990.dng, P5240991.dng, ..., P5240999.dng)的情况下,以下内容将将每组 10 文件视为一组(基于十位),并且每组内仅保留第一个文件:

1..99 | % { "P52409$('{0:00}' -f $_).dng" } | 
  Group-Object { $_ -replace '^(.+\d)\d\.', '$1' }   | 
   ? Count -gt 1 |
     % { $_.Group[1..$($_.Group.Count)]}

的产率:

# tens place of 0; skips ...01.dng
P5240902.dng
P5240903.dng
... # up to ...09.dng
# tens place of 1; skips ...10.dng
P5240911.dng
P5240912.dng
... # skips ...20.dng, ...30.dng, ...
# tens place of 9; skips ...90.dng
P5240991.dng
P5240992.dng
...
P5240999.dng

为了仅将感兴趣的文件传递给命令,请将示例输入数组替换为
Get-ChildItem P52515[0-9][0-9].dng

答案 1 :(得分:0)

假设dir中的所有内容都遵循命名约定&amp;是这样的一组3应该工作:

$mydir = 'C:\path\to\files'
[int]$idx = 1
get-childitem $mydir|sort-object {$_.Name} |foreach-object{
    if ($idx % 3 -ne 1){ #get the modulus
        $_ |remove-item
    }
    $idx++
}