Excel 从预先格式化的CSV中删除空行

Excel 从预先格式化的CSV中删除空行,excel,vba,csv,batch-file,filter,Excel,Vba,Csv,Batch File,Filter,我用VBA从XLS文件生成CSV,然后用批处理过滤CSV。我的过滤器如下所示: for %%a in (*.csv) do ( for /f "usebackq tokens=1-10 delims=, eol=^" %%1 in ("%%a") do ( if %%4 EQU Req_Category ECHO %%1,%%2,%%3,%%4,%%5,%%6,%%7,%%8,%%9 >> "%%a"_JIRA.csv if %%4 EQU Requiremen

我用VBA从XLS文件生成CSV,然后用批处理过滤CSV。我的过滤器如下所示:

for %%a in (*.csv) do (

  for /f "usebackq tokens=1-10 delims=, eol=^" %%1 in ("%%a") do (
    if %%4 EQU Req_Category ECHO %%1,%%2,%%3,%%4,%%5,%%6,%%7,%%8,%%9 >> "%%a"_JIRA.csv
    if %%4 EQU Requirement ECHO %%1,%%2,%%3,%%4,%%5,%%6,%%7,%%8,%%9 >> "%%a"_JIRA.csv
  )

)
如果CSV文件没有空行,则此操作可以正常工作。 在极少数情况下,XLS->CSV转换会在CSV中生成空行或CRs

SW_Fn-289,4.1.1.1,Controling Hardware PCB,Heading,,,,,IgnoreTesting,
SW_Fn-291,4.1.1.1.0-1," 
Date : 07.03.1777

The SystemDesignSpecification is stored in SVN path
http://sblablablabla.xlsm
",Requirement,Lab1 (B-Sample),,Released,Accepted,IgnoreTesting,
SW_Fn-4281,4.1.1.1.0-2," 
Date : 123.123.123

Path : https://apath.com
",Requirement,R1,,New,New,IgnoreTesting,
SW_Fn-166,4.2,Compliance Requirements,Heading,,,,,IgnoreTesting,
SW_Fn-286,4.2.1,Resource Usage,Heading,,,,,IgnoreTesting,
CSV中的每一行都应以ID开头:SW_Fn-Example。 每个人都知道如何使用批处理功能将信息放在一行上吗

我需要使文件看起来像这样(在筛选之前):

不应该有一行不以SW_Fn-blabla开头的。如果一行以其他内容开头,那么它应该是前一行的一部分,前一行有Sw_Fn-blabla

然后,我的过滤器将产生以下结果:

SW_Fn-291,4.1.1.1.0-1,"Date : 07.03.1777 TheSystemDesignSpecificationisstored in SVN path http://sblablablabla.xlsm",Requirement,Lab1 (B-Sample),,Released,Accepted,IgnoreTesting,
SW_Fn-4281,4.1.1.1.0-2," Date : 123.123.123 Path : https://apath.com",Requirement,R1,,New,New,IgnoreTesting,

提前感谢

Aak!不要对
元变量使用数字(
%%1
)-它非常不可靠。使用字母字符

批处理将一个分隔符字符串视为单个分隔符,并指定逗号和空格作为分隔符,因此

SW_Fn-166,4.2,Compliance Requirements,Heading,,,,,IgnoreTesting,
将显示为

SW_Fn-166,4.2,Compliance,Requirements,Heading,IgnoreTesting,,,,
您尚未显示您期望的输出。您是只希望以
SW\u Fn-
开头的行,还是希望将所有未以
SW Fn
开头的行附加到最后一行


@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
设置“destdir=U:\destdir”
设置“filename1=%sourcedir%\q36475816.csv”
设置“outfile=%destdir%\outfile.txt”
设置“行=”
(
对于/f“usebackqdelims=“%%a IN”(“%filename1%”)DO(
设置“newpart=%%a”
如果定义了线路调用:测试
如果定义了线路调用集“线路=%%线路%%%%a”
如果未定义行,则设置“行=%%a”
)
如果定义了行回音(%line%)
)>“%outfile%”
后藤:EOF
::测试新数据“将数据累积到行中或输出并开始新行
:测试
设置“newpart=%newpart:=x%”
如果不是“%newpart:~0,6%”,则为“SW_Fn-”转到:eof
回音(%line%)
设置“行=”
后藤:eof
您需要更改
sourcedir
destdir
的设置以适应您的环境

我使用了一个名为
q36475816.csv
的文件,其中包含用于测试的数据

生成定义为%outfile%的文件

请注意,您发布的数据在
Fn-4281
项中包含不平衡的引号。最好使用实际数据,而不是“在附近”

阅读每一行。如果我们已经积累了一行的一部分,请检查前几个字符是否是目标。如果是,请按构造输出该行,并清除

如果此操作后
line
被清除,则将其设置为行读取(必须从目标开始,否则累加行)

:test
过程中,在测试之前删除引号,这样它就不会破坏语法。显然,如果前几个字符包含引号,则它不符合目标,因此测试将正确检测到
“不符合”
请尝试以下操作:

@echo off
for %%a in (*.csv) do (
  for /f "delims=" %%b in (%%a) do (
    for /f "tokens=4 delims=," %%c in ("%%b") do (
      if "%%c"=="Requirement" echo %%b >>%%~na_JIRA%%~xa
      if "%%c"=="Req_Category" echo %%b >>%%~na_JIRA%%~xa
    )
  )
)

阅读并处理每一行完整内容,以克服Magoo提到的连续分隔符问题(使用另一个
for
检查标记4,但不要费心拆解和重新组装完整的行)

您的文件实际上是有效的CSV格式。引用的CSV字段可能包含以下任何内容:

  • 逗号
  • 引用文字,转义为
    “”
  • 换行符(左前或右后)
您的字段中没有逗号或引号,但有换行符会给代码带来严重问题

但这只是一个潜在的问题。另一个问题是FOR/F将连续分隔符视为单个分隔符,因此,如果您想要的任何一行中有任何空字段,那么您的输出将完全错误

批处理本质上并不适合任何类型的文本处理,但对于CSV来说,除了最简单的问题外,它对所有问题都特别不利。如果您真的想使用批处理,您可以使用正确解析CSV并以可靠的方式使用for/F读取它。但是有更好的选择

PowerShell有一个
Import-Csv
cmdlet。我不确定它的功能,但如果它支持字段中的换行符,那么您可以用它开发一个非常灵活的解决方案

另一个选项是my。以下代码看起来很糟糕,但它将在一个步骤中非常有效地生成所需的输出:

jrepl "((?:[\s\S]*?,){3}(?:(Req_Category,|Requirement,)|.*?,)(?:.*?,){4}.*?),[^,\n]*\n?" "$2?$1.replace(/\r\n/g,' ')+'\r\n':''" /m /j /f input.csv /o output.csv
如果将命令放在另一个批处理脚本中,则需要使用calljrepl

我的JREPL解决方案依赖于这样一个事实:您的任何输入字段都不包含带引号的逗号。如果它确实包含带引号的逗号,那么JREPL解决方案将更加复杂

此解决方案通过使用/M多行选项来工作,以便我可以跨换行符进行匹配

搜索将匹配每个10个字段集合(您的第10个字段似乎总是空的),而不考虑换行符。$1包含前9个字段(不带尾随逗号)。$2包含第4个字段,当且仅当它匹配“Req_Category”或“Requirement”时。替换javascript表达式测试是否定义了$2,如果定义了,则在所有换行符被空格替换后,整个搜索表达式将被替换为$1,然后追加一个换行符。如果未定义$2,则整个搜索表达式将被替换为空字符串。概念简单,但开发起来有点麻烦;-)

稍微简化一下,您就可以保留包含换行符的原始字段,并且仍然可以进行所需的筛选:

jrepl "((?:[\s\S]*?,){3}(?:(Req_Category,|Requirement,)|.*?,)(?:.*?,){4}.*?),[^,\n]*\n?" "$2?$1+'\r\n':''" /m /j /f input.csv /o output.csv

您好,我想把所有不以
Sw\u Fn-
开头的行添加到最后一行。感谢您在数字方面的技巧,并提前感谢根据您的过滤器,您所需输出的五行中有三行不应该在那里。我已经编辑了。今天有点累。如果信息打开,过滤器工作正常一行。如果信息被分割,我很难实现我的目标。如果您的转换不可靠,您可能更应该修复它,而不是对其进行后处理
jrepl "((?:[\s\S]*?,){3}(?:(Req_Category,|Requirement,)|.*?,)(?:.*?,){4}.*?),[^,\n]*\n?" "$2?$1+'\r\n':''" /m /j /f input.csv /o output.csv