如何使用批处理从 csv 文件中删除空白行?

How to remove blank rows from csv file using batch?

这是我第一次使用批处理文件进行编程,我被要求编写一个能够将 .xlsm 文件转换为 .csv 的程序,而无需打开 Excel 即可。为此,我使用了这个 .bat 文件:

extoc.vbs integration.xlsm integration.csv 
Taskkill /IM EXCEL.EXE /F

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION


call :StripBlankLines "integration.csv"

goto :eof
:StripBlankLines
For %%x in ("%~1") do set OutF=integration_er.csv
if exist "%OutF%" del "%OutF%"
set FirstLine=1
for /F "usebackq delims=" %%B in (%*) do (
    call :TrimWS %%B
    if not "!Line!"=="" (
        if "!FirstLine!"=="1" (
            set FirstLine=0
        ) else (
            >>"%OutF%" echo.
        )
        call :write !Line!
    )
)
goto :eof

:TrimWS
set Line=%*
goto :eof 

:write
>>"%OutF%"<NUL set /p Dummy=%*
goto :eof

连同 .vbs 文件:

if WScript.Arguments.Count < 2 Then
WScript.Echo "Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file>"
Wscript.Quit
End If

csv_format = 6

Set objFSO = CreateObject("Scripting.FileSystemObject")

src_file = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
dest_file = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))

Dim oExcel
Set oExcel = CreateObject("Excel.Application")

Dim oBook
Set oBook = oExcel.Workbooks.Open(src_file)

oBook.SaveAs dest_file, csv_format

oExcel.Quit

oBook.Close False

这里的问题是,作为最终结果,我得到了一个巨大的 CSV,其中包含原始 .xlsm 文件中的所有信息,还有几行只用逗号填充,如下所示:

data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,

虽然我需要这样的东西:

data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data

我知道这些逗号来自 excel 中的空白行,但我不能使用 VBA 宏删除 excel 中的所有空白行,因为它是一个巨大的sheet 每次我尝试这样做时,我的电脑都会崩溃。所以,如果有某种方法可以通过 VBS 或 BATCH 解决这个问题,我将非常高兴!

:TrimWS
set Line=%*
set "line=%line:,=%"
if defined line set "line=%*"
goto :eof 

line 中的每个 , 替换为 。如果结果是 nothing 那么 line 将是未定义的,即。空的。如果不是 re-load 则使用原始值。

顺便说一句 - 如果您将 FirstLine 设置为 nothing (set firstline=") 或 something (任何东西,只是not nothing) 然后你可以使用 if defined firstline 检测它的 current 状态所以你不需要 delayedexpansion.


(重写)

@echo off
SETLOCAL


call :StripBlankLines "integration.csv"

goto :eof
:StripBlankLines
For %%x in ("%~1") do set OutF=integration_er.csv
if exist "%OutF%" del "%OutF%"
set FirstLine=1
for /F "usebackq delims=" %%B in (%*) do (
    call :TrimWS %%B
    if defined line (
        if defined firstline (
            set "FirstLine="
        ) else (
            >>"%OutF%" echo.
        )
        call :write %%B
    )
)
goto :eof

:TrimWS
set Line=%*
set "line=%line:,=%"
goto :eof 

:write
>>"%OutF%"<NUL set /p Dummy=%*
goto :eof

由于 line 将包含与 %%B 相同的内容,您可以使用 %%B 提供 它不包含 just-commas.因此,您可以将 %%B 发送到您的 :trimws 例程,并且 line 将被设置为 nothing (在 all-commas 的情况下) 或 something (anything) 否则。

然后您可以简单地解释 line 是否已定义以通过您的 :write 例程输出 %%B,因为 :write 仅在 [=20] 时被调用=] 不包含 all-commas 但也不为空(for/f 会处理)。

开始时将 firstline 设置为 something 意味着 if defined firstline 最初为真,因此您将其设置为 nothing 之后 if defined firstline 将为假。

语法 SET "var=value"(其中值可能为空)用于确保分配的值中不包含任何杂散尾随空格。

setlocal 应该保留,以便 cmd 环境不会像批处理例程 运行 那样累积值。它确保在例程终止时丢弃对环境变量所做的任何更改

除非我误会了,否则为什么不只使用一行:

FindStr "[^,]" "integration.csv">"integration_er.csv"