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

时间:2018-03-20 17:02:57

标签: excel csv batch-file vbscript export-to-csv

这是我第一次使用批处理文件进行编程时,我被要求执行一个能够将.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中的所有空行,因为它是一张巨大的工作表,每当我尝试这样做时我的电脑都会崩溃。所以,如果有办法通过VBS或BATCH解决这个问题,我真的很高兴!

2 个答案:

答案 0 :(得分:1)

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

,中的每个line替换为 nothing 。如果结果是 nothing ,那么line将是未定义的,即。空。如果它没有用原始值重新加载它。

顺便说一句 - 如果您将FirstLine设置为没有set firstline=")或某些(任何内容,只是没有 >)然后您可以使用if defined firstline检测其当前状态,这样您就不需要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 提供它不包含逗号。因此,您可以将%%B发送到:trimws例程,line将设置为 nothing (在所有逗号的情况下)或 (任何东西)否则。

然后,您可以简单地解释line被定义或不通过%%B例程输出:write,因为:write只会在%%B时调用不包含所有逗号,但也不是空的(for/f会处理它)。

在开始时将firstline设置为某些内容意味着if defined firstline最初为真,因此您将其设置为 nothing ,之后{{1将是假的。

语法if defined firstline(其中value可能为空)用于确保任何杂散尾随空格不包含在分配的值中。

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

答案 1 :(得分:1)

除非我误解,为什么不只使用一行:

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