如何检查csv文件中每行的列数?

时间:2010-11-10 15:50:11

标签: windows batch-file cmd

我有一个包含数万行的大文件,其中包含|分隔的数据,用于我的数据库中的批量插入。 我知道应该说10列。

由于某些数据可能会意外地包含分隔符|,因此可能会发生错误,因为此行的列数不匹配。

我正在尝试计算超过20列的行数来检查文件是否有效:

@ECHO OFF
set /a count=0
FOR /f "tokens=10,* delims=|" %%i in (%1) DO (
  if not "%%j"=="" (
    set /a count+=1
  )
)
echo %count%
:eof

它运行良好...但只有当没有任何字段为空时,才会移动计数,因为delims处理像空格一样的分隔符

e.g  
    1|2|3|4|5|6|7|8|9|10 => cool, 10 columns
    1|2|3|4|5|6|7|8|almost got|you|10 => found 11 columns 
    1|2|3|4||6|7|8|got|you|10 => damn, reports as 10 columns

如何仅使用命令行/ Windows批处理解决此问题?

N.B。我无法修改文件以将数据括在引号或其他内容中。

1 个答案:

答案 0 :(得分:1)

您可以使用findstr并为其提供正则表达式。因此,假设您知道您的行至少有10列,这意味着它至少有9个管道符。并且您想要查找哪些行具有10个或更多管道字符。我们可以拿出这个正则表达式:

.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*  Line has at least 10 pipe characters, meaning
                                  some data field contains a pipe character.

将该正则表达式赋予findstr

findstr /R ".*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*" data.txt

这会打印所有格式错误的行。将其输出提供给find /c以计算它吐出的行数。

findstr /R ".*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*" data.txt | find /c "|"

示例data.txt

1|2|3|4|5|6|7|8|9|10                 good - 10 columns
1|2|3|4|5|6|7|8|almost got|you|10    bad  - 11 columns
1|2|3|4||6|7|8|got|you|10            bad  - 11 columns
1|2|3|4|5|6|7|8|9||                  bad  - 11 columns
1|2|3|4|5|6|7|8|9                    good - 10 columns
1|2|3|4|5|6|7                        gotcha - less than 10 columns not detected
1|2|3|4|5|6|7|8|9|                   good - 10 columns
|||||||||                            good - 10 columns
||||||||||                           bad  - 11 columns

C:\>findstr /R "^.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*$" data.txt
1|2|3|4|5|6|7|8|almost got|you|10    bad  - 11 columns
1|2|3|4||6|7|8|got|you|10            bad  - 11 columns
1|2|3|4|5|6|7|8|9||                  bad  - 11 columns
||||||||||                           bad  - 11 columns

C:\>findstr /R "^.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*$" data.txt | find /c "|"
4