Search code examples
powershellfilecsvimportexport-to-csv

From a CSV file get the file header and a portion of the file based on starting and ending line number parameters using PowerShell


So I have a very huge CSV file, the first line has the column headers. I want to keep the first line as a header and add a portion of the file from the file's mid-section or perhaps the end. I'm also trying to select only a few of the columns from the file. And finally, it would be great if the solution also changed the file delimiter from a comma to a tab.

I'm aiming for a solution that's a one-liner or perhaps 2?

Non-working Code version 30 ...

Get-Content -Tail 100 filename.csv | Export-Csv -Delimiter "`t" -NoTypeInformation -Path .\filename_out.csv

I'm trying to get a better grip on PowerShell. So far, so good but I'm not quite there yet. But trying to solve such challenges are helping me (and hopefully others) build a good collection of coding idioms. (FYI - the boss is trying PowerShell due to our efforts so.)


Solution

  • iRon provided the crucial pointer: Using Import-Csv rather than Get-Content allows you to retrieve arbitrary ranges from the original file as objects, if selected via Select-Object, and exporting these objects again via Export-Csv automatically includes a header line whose column names are the input objects' property names, as initially derived from the input file's header line.

    In order to select an arbitrary range of rows, combine Select-Object's -Skip and -First parameters:

    • To only get rows from the beginning, use just -First $count:

    • To only get rows from the end, use just -Last $count

    • To get rows in a given range, use just -Skip $startRowMinus1 -First $rangeRowCount

    For instance, the following command extracts rows 10 through 30:

    Import-Csv iarf.csv | 
      Select-Object -Property Id,Name,RecordTypeId,CreatedDate -Skip 9 -First 20 |
        Export-Csv -Delimiter "`t" -NoTypeInformation -Path .\iarf100props6.csv