Remove Top Line of Text File with PowerShell

后端 未结 10 1238
误落风尘
误落风尘 2020-12-01 11:51

I am trying to just remove the first line of about 5000 text files before importing them.

I am still very new to PowerShell so not sure what to search for or how to

相关标签:
10条回答
  • 2020-12-01 12:12

    skip` didn't work, so my workaround is

    $LinesCount = $(get-content $file).Count
    get-content $file |
        select -Last $($LinesCount-1) | 
        set-content "$file-temp"
    move "$file-temp" $file -Force
    
    0 讨论(0)
  • 2020-12-01 12:15

    While I really admire the answer from @hoge both for a very concise technique and a wrapper function to generalize it and I encourage upvotes for it, I am compelled to comment on the other two answers that use temp files (it gnaws at me like fingernails on a chalkboard!).

    Assuming the file is not huge, you can force the pipeline to operate in discrete sections--thereby obviating the need for a temp file--with judicious use of parentheses:

    (Get-Content $file | Select-Object -Skip 1) | Set-Content $file
    

    ... or in short form:

    (gc $file | select -Skip 1) | sc $file
    
    0 讨论(0)
  • 2020-12-01 12:18

    I just had to do the same task, and gc | select ... | sc took over 4 GB of RAM on my machine while reading a 1.6 GB file. It didn't finish for at least 20 minutes after reading the whole file in (as reported by Read Bytes in Process Explorer), at which point I had to kill it.

    My solution was to use a more .NET approach: StreamReader + StreamWriter. See this answer for a great answer discussing the perf: In Powershell, what's the most efficient way to split a large text file by record type?

    Below is my solution. Yes, it uses a temporary file, but in my case, it didn't matter (it was a freaking huge SQL table creation and insert statements file):

    PS> (measure-command{
        $i = 0
        $ins = New-Object System.IO.StreamReader "in/file/pa.th"
        $outs = New-Object System.IO.StreamWriter "out/file/pa.th"
        while( !$ins.EndOfStream ) {
            $line = $ins.ReadLine();
            if( $i -ne 0 ) {
                $outs.WriteLine($line);
            }
            $i = $i+1;
        }
        $outs.Close();
        $ins.Close();
    }).TotalSeconds
    

    It returned:

    188.1224443
    
    0 讨论(0)
  • 2020-12-01 12:18
    $x = get-content $file
    $x[1..$x.count] | set-content $file
    

    Just that much. Long boring explanation follows. Get-content returns an array. We can "index into" array variables, as demonstrated in this and other Scripting Guys posts.

    For example, if we define an array variable like this,

    $array = @("first item","second item","third item")
    

    so $array returns

    first item
    second item
    third item
    

    then we can "index into" that array to retrieve only its 1st element

    $array[0]
    

    or only its 2nd

    $array[1]
    

    or a range of index values from the 2nd through the last.

    $array[1..$array.count]
    
    0 讨论(0)
  • 2020-12-01 12:19

    It is not the most efficient in the world, but this should work:

    get-content $file |
        select -Skip 1 |
        set-content "$file-temp"
    move "$file-temp" $file -Force
    
    0 讨论(0)
  • 2020-12-01 12:19

    I just learned from a website:

    Get-ChildItem *.txt | ForEach-Object { (get-Content $_) | Where-Object {(1) -notcontains $_.ReadCount } | Set-Content -path $_ }
    

    Or you can use the aliases to make it short, like:

    gci *.txt | % { (gc $_) | ? { (1) -notcontains $_.ReadCount } | sc -path $_ }
    
    0 讨论(0)
提交回复
热议问题