Copy lines from .csv file into another .csv file using batch script

前端 未结 2 1349
日久生厌
日久生厌 2021-01-24 06:38

I am creating .csv files from a device (output) and need to copy a specific number of lines from this file into another .csv file which has the same format.

They are luc

相关标签:
2条回答
  • 2021-01-24 07:06

    To illustrate why you don't want to do this in batch, this is the code to copy lines 68 through 107 to another file in VBScript:

    inputFilename  = "C:\path\to\input.csv"
    outputFilename = "C:\path\to\output.csv"
    fromLine = 68
    toLine   = 107
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set inFile  = fso.OpenTextFile(inputFilename)
    Set outFile = fso.OpenTextFile(outputFilename, 2, True)
    
    Do Until inFile.AtEndOfStream Or inFile.Line > toLine
      line = inFile.ReadLine
      If inFile.Line >= fromLine Then outFile.WriteLine line
    Loop
    
    inFile.Close
    outFile.Close
    

    To illustrate why you don't want to do this in VBScript either, this is the same operation in PowerShell:

    $inputFile  = 'C:\path\to\input.csv'
    $outputFile = 'C:\path\to\output.csv'
    $fromLine   = 68
    $toLine     = 107
    
    $skip       = $fromLine - 1
    $numLines   = $toLine - $skip
    
    Get-Content $inputFile | Select-Object -Skip $skip -First $numLines |
        Set-Content $outputFile
    

    which could be simplified to:

    $inputFile  = 'C:\path\to\input.csv'
    $outputFile = 'C:\path\to\output.csv'
    $skip       = 67
    $numLines   = 40
    
    Get-Content $inputFile | Select-Object -Skip $skip -First $numLines |
        Set-Content $outputFile
    

    You can even preserve the CSV header if you want:

    $inputFile  = 'C:\path\to\input.csv'
    $outputFile = 'C:\path\to\output.csv'
    $skip       = 66
    $numLines   = 40
    
    Import-Csv $inputFile | Select-Object -Skip $skip -First $numLines |
        Export-Csv $outputFile -NoType
    
    0 讨论(0)
  • 2021-01-24 07:13

    There is absolutely no need to use a batch file that creates and invokes a VBScript.


    You could accomplish the task by a pure batch script like this:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    
    rem // Define constants here:
    set "_FILEIN=!USERPROFILE!\Desktop\Dev\Test\Default.csv"
    set "_FILEOUT=!USERPROFILE!\Desktop\Dev\Test\OutputData.csv"
    set /A "_LINEFROM=68"
    set /A "_LINETO=107"
    
    rem // Count number of lines of input file:
    for /F %%C in ('^< "!_FILEIN!" find /C /V ""') do (
        rem // Read and write files using redirection:
        < "!_FILEIN!" > "!_FILEOUT!" (
            rem // Iterate through all available lines:
            for /L %%I in (1,1,%%C) do (
                rem // Read a single line:
                set "LINE=" & set /P LINE=""
                rem // Check position (line number) of current line:
                if %%I GEQ %_LINEFROM% if %%I LEQ %_LINETO% (
                    rem // Return current line conditionally:
                    echo(!LINE!
                )
            )
        )
    )
    
    endlocal
    exit /B
    

    Note that pure batch file solutions may be limited in line lengths and file sizes. The aforementioned approach cannot handle lines longer than 1023 bytes and files with more than 2147483647 lines.


    Here is another but slower pure batch script solution:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "_FILEIN=%USERPROFILE%\Desktop\Dev\Test\Default.csv"
    set "_FILEOUT=%USERPROFILE%\Desktop\Dev\Test\OutputData.csv"
    set /A "_LINEFROM=68"
    set /A "_LINETO=107"
    
    rem // Write file using redirection:
    > "%_FILEOUT%" (
        rem // Read file using a loop, prefixed with line index:
        for /F "delims=" %%L in ('findstr /N "^" "%_FILEIN%"') do (
            rem // Extract line number:
            2> nul set /A "IDX=%%L"
            rem // Read current line:
            set "LINE=%%L"
            setlocal EnableDelayedExpansion
            rem // Check position (line number) of current line:
            if !IDX! GEQ %_LINEFROM% if !IDX! LEQ %_LINETO% (
                rem // Return current line conditionally:
                echo(!LINE:*:=!
            )
            endlocal
        )
    )
    
    endlocal
    exit /B
    

    This approach cannot handle lines longer than 8191 - 7 = 8184 bytes and files with more than 2147483647 lines.

    0 讨论(0)
提交回复
热议问题