使用批处理脚本将.csv文件中的行复制到另一个.csv文件中

时间:2017-05-18 04:13:35

标签: csv batch-file vbscript

我正在从设备(输出)创建.csv文件,需要将此文件中的特定行数复制到另一个格式相同的.csv文件中。

幸运的是它们的格式相同,因此每个文件都有相同的行要复制(第68到107行)。我已经使用其他来源的代码,但我迄今为止所能做的就是复制数据,但无法将其插入到其他文件中。任何帮助都会很棒!

@echo off

Set "InputFile=C:\*****\Desktop\Dev\Test\Default.csv"
Set "OutPutFile=C:\*****\Desktop\Dev\Test\OutputData.csv"
Set FromLine=68
Set ToLine=107

Call:ExtractLinesFromTextFile "%InputFile%" %FromLine% %ToLine% > 
"%OutPutFile%"

Exit /b

:ExtractLinesFromTextFile <InputFile> <FromLine> <ToLine>
(
echo Wscript.echo(ExtractLinesFromTextFile("%~1",%2,%3^)^)
echo Function ExtractLinesFromTextFile(TextFile,FromLine,ToLine^)
echo If FromLine ^<= ToLine Then
echo With CreateObject("Scripting.FileSystemObject"^).OpenTextFile(TextFile^)
echo Do Until .Line = FromLine Or .AtEndOfStream
echo .SkipLine
echo Loop
echo Do Until .Line ^> ToLine Or .AtEndOfStream
echo ExtractLinesFromTextFile = ExtractLinesFromTextFile ^& (.ReadLine ^& 
vbNewLine^)
echo Loop
echo End With
echo End If
echo End Function
)>"%~n0.vbs"
Cscript /Nologo "%~n0.vbs" "%~1" %~2 %~3
If Exist "%~n0.vbs" Del "%~n0.vbs"
Exit /b

2 个答案:

答案 0 :(得分:0)

绝对不需要使用创建和调用VBScript的批处理文件。

您可以通过这样的纯批处理脚本完成任务:

@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

请注意,纯批处理文件解决方案可能会受到行长度和文件大小的限制。上述方法不能处理长度超过1023字节的行和处理超过2147483647行的文件。

这是另一个但速度较慢的纯批处理脚本解决方案:

@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

此方法无法处理超过8191 - 7 = 8184字节的行和超过2147483647行的文件。

答案 1 :(得分:0)

为了说明您不希望批量执行此操作的原因,这是将第68行到第107行复制到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

为了说明您不希望在VBScript中执行此操作的原因,这与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

可以简化为:

$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

如果需要,您甚至可以保留CSV标题:

$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