【问题标题】:PowerShell equivalent for "head -n-3"?“head -n-3”的PowerShell等效项?
【发布时间】:2012-04-22 04:50:25
【问题描述】:

我已经能够追踪基本的头/尾功能:

head -10 myfile <==> cat myfile | select -first 10
tail -10 myfile <==> cat myfile | select -last 10

但是如果我想列出除最后三行之外的所有行或除前三行之外的所有行,你该怎么做?在 Unix 中,我可以执行“head -n-3”或“tail -n+4”。 PowerShell 应该如何完成这一点并不明显。

【问题讨论】:

    标签: powershell tail unix-head


    【解决方案1】:

    有用的信息在此处分散在其他答案中,但我认为有一个简洁的摘要很有用:

    三行以外的所有行

    1..10 | Select-Object -skip 3
    returns (one per line): 4 5 6 7 8 9 10
    

    最后三行以外的所有行

    1..10 | Select-Object -skip 3 -last 10
    returns (one per line): 1 2 3 4 5 6 7
    

    也就是说,您可以使用内置的 PowerShell 命令来执行此操作,但是必须指定输入的大小会很烦人。一个简单的解决方法是只使用一个比任何可能都大的常量输入,您不需要先验地知道大小:

    1..10 | Select-Object -skip 3 -last 10000000
    returns (one per line): 1 2 3 4 5 6 7
    

    正如 Keith Hill 建议的那样,更简洁的语法是使用 PowerShell Community Extensions 中的 Skip-Object cmdlet(Goyuix 的答案中的 Skip-Last 函数执行相同,但使用 PSCX 可以让您不必维护代码):

    1..10 | Skip-Object -last 3
    returns (one per line): 1 2 3 4 5 6 7
    

    三行

    1..10 | Select-Object –first 3
    returns (one per line): 1 2 3
    

    最后三行

    1..10 | Select-Object –last 3
    returns (one per line): 8 9 10
    

    中间四行

    (这是因为-skip-first 之前处理,无论调用中参数的顺序如何。)

    1..10 | Select-Object -skip 3 -first 4
    returns (one per line): 4 5 6 7
    

    【讨论】:

      【解决方案2】:

      与 -First 和 -Last 参数一样,还有一个 -Skip 参数会有所帮助。值得注意的是,-Skip 是从 1 开始的,而不是从零开始的。

      # this will skip the first three lines of the text file
      cat myfile | select -skip 3
      

      我不确定 PowerShell 是否有什么东西可以让您返回所有内容,除了预先构建的最后 n 行。如果您知道长度,您可以从行数中减去 n 并使用 select 中的 -First 参数。您还可以使用仅在填充时通过行的缓冲区。

      function Skip-Last {
        param (
          [Parameter(Mandatory=$true,ValueFromPipeline=$true)][PsObject]$InputObject,
          [Parameter(Mandatory=$true)][int]$Count
        )
      
        begin {
          $buf = New-Object 'System.Collections.Generic.Queue[string]'
        }
      
        process {
          if ($buf.Count -eq $Count) { $buf.Dequeue() }
          $buf.Enqueue($InputObject)
        }
      }
      

      作为演示:

      # this would display the entire file except the last five lines
      cat myfile | Skip-Last -count 5
      

      【讨论】:

        【解决方案3】:

        如果您使用的是PowerShell Community Extensions,则有一个 Take-Object cmdlet 将传递除最后 N 项之外的所有输出,例如:

        30# 1..10 | Skip-Object -Last 4
        1
        2
        3
        4
        5
        6
        

        【讨论】:

          【解决方案4】:

          你可以这样做:

          [array]$Service = Get-Service
          $Service[0] #First Item
          $Service[0..2] #First 3 Items
          $Service[3..($Service.Count)] #Skip the first 3 lines
          $Service[-1] #Last Item
          $Service[-3..-1] #Last 3 Items
          $Service[0..($Service.Count -4)] #Skip the last 3 lines
          

          【讨论】:

            【解决方案5】:

            除了最后一个 n 之外的所有内容都可以使用

            ... | select -skiplast $n
            

            【讨论】:

              【解决方案6】:

              除了第一个 n 之外的所有内容都可以使用

              ... | Select -skip $n
              

              但是,所有“除了最后一个m”都没有内置任何内容。将整个输入加载到一个数组中以获得长度是可行的——当然对于可能对内存提出不合理要求的大输入。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多