【问题标题】:Run a function on each element of a list in powershell对powershell中列表的每个元素运行一个函数
【发布时间】:2009-08-08 01:45:14
【问题描述】:

我有一个充满文件对的目录。每对文件具有相同的名称,扩展名为 mp3 和 cdg(卡拉 OK 文件!)。我想使用 powershell 来获取所有不带扩展名的不同文件名的列表

我已经做到了:

dir -recurse -filter "*.mp3" | select-object Name | sort

但我不太清楚如何将每个名称传递给 [System.IO.Path]::GetFileNameWithoutExtension

我该怎么做?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您正在寻找的是 for-each (%) 过滤器(不确定它是过滤器还是 cmdlet,但它具有相同的用法语法)。

    试试下面的

    dir -recurse -filter "*.mp3" | 
      %{ $_.Name } |
      %{ [IO::Path]::GetFileNameWithoutExtension($_) } |
      sort
    

    编辑更新

    我将答案从“select-object Name”更改为“%{ $_.Name}”。前者实质上是从管道值中取出 Name 属性,并创建一个新对象,该对象具有指定名称的单个属性和原始对象上的值。后者将处理管道中的每个值,并将执行$_.Name 的结果传递到管道中。

    【讨论】:

    • 这行得通,但是 a) 它给了我类似的东西:@{Name=Mr Bungle - Backstrokin' - 我如何摆脱 @{Name= 部分? b) 我到底做了什么?
    • @George,我更新了我的答案以摆脱 @Name 部分。我将添加一个关于为什么会发生这种情况的回应
    • foreach-object 是一个函数。您可以使用 gcm 或简单地通过观察 % { "begin" } { "processing $_" } { "end" } 按预期工作来验证这一点。
    • ForEach-Object 在这里是一个 cmdlet。
    • 'Function' 和 'cmdlet' 或多或少是同义词 - 如果您考虑 v2.0 中的高级功能,肯定是这样。重要的一点是,% 不能是过滤器,因为过滤器没有 Begin & End 块。
    【解决方案2】:

    dir -recurse -filter "*.mp3"|选择@{name='Name';Expression={[System.IO.Path]::GetFileNameWithoutExtension($_.Name)}} |排序

    【讨论】:

    • +1。许多人忘记了 select 的“哈希表语法”。可惜太丑了写 select @{ Name = {some-expression}, Path = {some-otherexpression} } 会更好
    【解决方案3】:

    如果您像我一样讨厌一直输入 %{$_.foo},请尝试来自 PSCX 的 Get-PropertyValue(别名:gpv)。

    这里有更多适合极客的想法:http://richardberg.net/blog/?p=55

    【讨论】:

      【解决方案4】:

      现在 PowerShell v2 是 RTMd,您可以选择 BaseName 成员:

      dir -recurse -filter *.mp3 |选择 BaseName |排序

      【讨论】:

        猜你喜欢
        • 2020-12-10
        • 1970-01-01
        • 2011-11-10
        • 1970-01-01
        • 1970-01-01
        • 2010-10-04
        • 2020-02-22
        • 1970-01-01
        • 2017-11-04
        相关资源
        最近更新 更多