简体   繁体   English

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

[英]How to remove blank rows from csv file using batch?

It's my first time programming with batch files and I was asked to do a program capable of converting .xlsm files into .csv, without having to open Excel to do so. 这是我第一次使用批处理文件进行编程,我被要求做一个能够将.xlsm文件转换为.csv的程序,而无需打开Excel即可。 To do so, I use this .bat file: 为此,我使用以下.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

Together with the .vbs file: 与.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

The problem in here is that I get, as a final result, a giant CSV containing all the information from the original .xlsm file, but also several lines filled with nothing but commas, as you can see bellow: 这里的问题是,最终,我得到一个巨大的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
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,

While I need to have something like this: 虽然我需要这样的东西:

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

I know these commas come from blank rows in excel, but I can't use a VBA Macro to remove all the blank rows in excel because it is a HUGE sheet and my PC crashes everytime I try to do it. 我知道这些逗号来自excel中的空白行,但是我无法使用VBA宏删除excel中的所有空白行,因为这是一个巨大的工作表,并且每次尝试执行操作时PC都会崩溃。 So, if there's some way to solve this through VBS or BATCH I would be REALLY glad! 因此,如果有某种方法可以通过VBS或BATCH解决此问题,我将非常高兴!

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

Replace each , in line with nothing . 替换每个,line 什么也没有 If the result is nothing then line will be undefined, ie. 如果结果为空,line不确定。 empty. 空的。 If it isn't re-load it with the original value. 如果不是,请使用原始值重新加载。

BTW - If you set FirstLine to nothing ( set firstline=" ) or something (anything, just not nothing ) then you can use if defined firstline to detect its current state so you don't need delayedexpansion . 顺便说一句-如果您将FirstLine设置为set firstline=" )或其他任何东西 (什么都不是, 什么都不是 ),则可以使用if defined firstline来检测其当前状态,因此您不需要delayedexpansion


(rewritten) (改写)

@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

Since line will contain the same as %%B , you can use %%B provided it doesn't consist of just-commas. 由于line将包含与%%B相同的line ,因此您可以使用%%B 前提是它不包含逗号。 Hence you can despatch %%B to your :trimws routine, and line will be set to either nothing (in the case of all-commas) or something (anything) otherwise. 因此,你可以寄发%%B:trimws套路, line会被设置为 (在全逗号的情况下)或东西 (什么),否则。

You can then simply interpret line being either defined or not to output %%B through your :write routine, as :write will only be invoked when %%B does not contain all-commas but also isn't empty (the for/f will take care of that). 然后,您可以简单地解释line被定义或不输出%%B通过您:write程序,如:write的时候才会被调用%%B不包含所有逗号,但也不是空( for/f会照顾的)。

Setting firstline to something at the start means if defined firstline will be true initially, so you set it to nothing and thereafter if defined firstline will be false. 设置firstline在开始的东西意味着if defined firstline将真正开始,所以将它设置为 ,然后if defined firstline将是错误的。

The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. 语法SET "var=value" (值可能为空)用于确保分配的值中不包含任何杂散尾随空格。

The setlocal should remain in order that the cmd environment does not accumulate values as batch routines run. 应该保留setlocal ,以便在批处理例程运行时cmd环境不会累积值。 It ensures that any changes made to the environment variables are discarded when the routine terminates 它确保例程终止时对环境变量所做的任何更改都被丢弃

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM