在路径中查找唯一的文件名部分

时间:2019-04-18 16:06:45

标签: shell powershell parsing

我有一个文件夹,其中包含一堆文件,格式为xxxxxx_MMddyyHHmmss.json。我想找到唯一的xxxxxx组件,因为有些是在不同时间创建的重复项。

我提到了this问题,但是作为一个很少尝试使用Powershell的人,我无法使其正常工作。

$result = Get-ChildItem  C:\Users\<me>\Desktop\FileData\* -recurse -name -include *.json|%{$_.split("_")[0]|sort-object -unique

但是我无法真正执行它。按下回车键时,它会转到下一行。

理想情况下,我可以将其传输到文件中进行审核。

1 个答案:

答案 0 :(得分:2)

您的命令中存在语法错误(%ForEach-Object)调用的脚本块({ ... })缺少结尾}),但它应该在原理。

一个精简,更快,更易读的版本是这样的:

Get-ChildItem $HOME\Desktop\FileData -Recurse -Filter *.json | 
  ForEach-Object { ($_.Name -split '_')[0] } |  
    Sort-Object -Unique
  • Get-ChildItem $HOME\Desktop\FileData -Recurse -Filter *.json返回*.json

  • 的目录子树中所有$HOME\Desktop\FileData文件的文件信息对象
  • ForEach-Object { ($_.Name -split '_')[0] }将每个文件信息输入对象转换为其名称的第一个_分隔标记。

    • 请注意,我已经从使用.NET [string]类型的.Split() 方法$_.Split("_")[0])切换为使用PowerShell的{{1} } operator -split),因为-split is generally preferable for its flexibility

    • 也就是说,当性能很重要时,($_ -split "_")[0]会明显更快

  • .Split()然后对结果标记进行排序,并仅返回唯一的标记(省略重复项)。

  • 使用Sort-Object -Unique而不是-Filter *.json可以加快文件检索的速度,因为-Include *.json参数由于源过滤而更加有效。


高级替代解决方案:

TheMadTechnician建议使用Group-Object,它允许您保留有关共享给定前缀的各个输入文件的信息:

-Filter

注意:如果不需要唯一前缀进行排序,则可以省略Get-ChildItem $HOME\Desktop\FileData -Recurse -Filter *.json | Group-Object { ($_.Name -split '_')[0] } | Sort-Object Name 调用,在这种情况下,它们将按以下顺序出现在文件遍历期间会遇到它们。

这将导致输出对象在属性Sort-Object中包含唯一的前缀,以及在.Name属性中具有该前缀的所有文件,其输出内容如下:

Group

要获得 just 唯一的前缀,如在第一个命令中一样,请将整个命令包装在Count Name Group ----- ---- ----- 2 abcdef {/tmp/abcdef_file1, /tmp/abcdef_file1} ... 中。

TheMadTechnician还建议提取前缀的方法稍微快一些(尽管可能会更晦涩):(...).Name使用-replace operator删除名称中第一个$_.Name -replace '_.*'中的所有内容。
但是,_仍然是整体上最快的解决方案。