我有一个包含数万行的大文件,其中包含|
分隔的数据,用于我的数据库中的批量插入。
我知道应该说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。我无法修改文件以将数据括在引号或其他内容中。
答案 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