正则表达式是美妙的东西 :) 您可以使用名为 REPL.BAT 的混合 JScript/批处理实用程序,它在标准输入上执行正则表达式搜索和替换,并将结果写入标准输出。
假设 REPL.BAT 在您的当前目录中,或者更好的是,在您的路径中的某个地方,那么以下一个衬里直接从命令行工作:
repl "^(?:[^,]*,){3}(\q[^\q]*\q).*$" "$1\n" mx <input.csv >output.txt
请注意,上述解决方案假设每条记录至少包含 4 列(3 个逗号)。它还假设前 3 列的值中不包含任何逗号,第 4 列必须被引用并且不能包含转义的引号""
,并且第 4 列之后的任何列的值中都不包含新行。如果不满足这些条件,所有的地狱都可能会崩溃。
使用更复杂的正则表达式,我有一个解决方案应该提取任何有效 csv 文件的第 4 列。它正确处理引用和未引用的值。引用的值可能包含逗号、转义引号和/或换行符。第 4 列输出将始终被引用,即使源不是。唯一的限制是每条记录必须至少包含 4 列。
repl "^(?:(?:[^,\q\n]*|\q(?:[^\q]|\q\q)*\q),){3}(?:\q((?:[^\q]|\q\q)*)\q|([^,\q\n]*))(?:,(?:[^,\q\n]*|\q(?:[^\q]|\q\q)*\q))*$" "\q$1$2\q" mx <input.csv >output.txt
这是一个讨厌的测试用例 csv 文件:
1,"50,
""ignore""
x","1","Warning! Q1: Value too high [W-0001]",extra," hello,""world""
more!","part A
1,2,3","I don't want this",<last column of record 1>
"2","49","1","Warning! Q1: Value too low [W-0002]",<last column of record 2>
"3","48","1","Warning! Q1: Value changing too fast.
Check for endless loop[W-0003]","<last column of record 3>"
1,2,3,"I want this part 1
and ""this"" part 2",<last column of record 4>
a,b,c,I want this unquoted value,<last column of record 5>
这是输出:
"Warning! Q1: Value too high [W-0001]"
"Warning! Q1: Value too low [W-0002]"
"Warning! Q1: Value changing too fast.
Check for endless loop[W-0003]"
"I want this part 1
and ""this"" part 2"
"I want this unquoted value"
使用批处理变量有助于记录正则表达式的逻辑,并可以轻松快速地捕获任意列集。这是使用变量的相同解决方案:
@echo off
setlocal
:: define a regex that matches a non-captured column value
set "ignore=(?:[^,\q\n]*|\q(?:[^\q]|\q\q)*\q)"
:: define a regex that matches a captured column value
:: quoted value is in $1, unquoted value is in $2
set "capture=(?:\q((?:[^\q]|\q\q)*)\q|([^,\q\n]*))"
call repl "^(?:%ignore%,){3}%capture%(?:,%ignore%)*$" "\q$1$2\q" mx <input.csv >output.txt
type output.txt
这是捕获第 1 列和第 4 列的最终 CALL 的演示
call repl "^%capture%,%ignore%,%ignore%,%capture%(?:,%ignore%)*$" "\q$1$2\q,\q$3$4\q" mx <input.csv >output.csv