Search code examples
powershelltext-filesline-numbers

How to extract specific line from text file


I got a large log file (user.log) , eg:

   2019-10-02 00:03:55.407095
   2019-10-02 00:03:55.410345
   2019-10-02 00:03:55.410765
   2019-10-02 00:03:55.411187
   2019-10-02 00:03:55.411791
   2019-10-02 00:03:55.412657

How do I just extract the line number #3 from the log file as;

2019-10-02 00:03:55.410765

By using powershell script?


Solution

  • A simple and memory-efficient approach suitable for processing large input files is to combine Get-Content with Select-Object:

    Get-Content user.log | Select-Object -Skip 2 -First 1
    
    • -Skip 2 instructs Select-Object to skip the first 2 input lines output by Get-Content.

    • Therefore, it is the 3rd line that is the first processed - and output - by Select-Object, and
      -First 1 makes it stop processing right afterwards, so that the rest of the file needn't be read.


    A faster approach, IF the portion of the file up to the desired line number is small enough to fit into memory as a whole:

    (Get-Content -TotalCount 3 -ReadCount -3 user.log)[-1]
    
    • -TotalCount 3 tells Get-Content to read 3 lines (at most) in total.

      • -ReadCount 3 additionally tells Get-Content to read all 3 lines at once into an array and send it through the pipeline as a single object - rather than line by line - this isn't necessary, but speeds up the command.
    • [-1] then extracts the last element from the resulting array, which is the 3rd line.


    If the input file as a whole is small, the following solution is simplest:

    (Get-Content user.log)[2]  # add -ReadCount 0 to speed things up
    

    That is, Get-Content reads all lines, which (...) collects in an array in memory, and [2] accesses the array's 3rd element, i.e., the 3rd line.

    A simple way of speeding up this solution would be to add -ReadCount 0, which makes Get-Content emit the array of all input lines itself, as a single output object, as opposed to emitting lines one by one and letting (...) collect them in an array afterwards.