Batch file RegEx可以在在线模拟器上工作,但不能在带有findstr的批处理文件中工作

Batch file RegEx可以在在线模拟器上工作,但不能在带有findstr的批处理文件中工作,batch-file,cmd,findstr,Batch File,Cmd,Findstr,我试图设置一个批处理文件,该文件使用findstr终止具有特定模式的所有行。我要分析的源文件如下所示:我将除第16位以外的所有值都改为数字,通常是名称、URL、空字符或单个字符,如Y/N: ProductCode|SkuID|Bestellnr|ProductName|locale_de-DE_ProductName|locale_it-IT_ProductName|locale_nl-NL_ProductName|locale_fr-FR_ProductName|locale_en-GB_Pr

我试图设置一个批处理文件,该文件使用findstr终止具有特定模式的所有行。我要分析的源文件如下所示:我将除第16位以外的所有值都改为数字,通常是名称、URL、空字符或单个字符,如Y/N:

ProductCode|SkuID|Bestellnr|ProductName|locale_de-DE_ProductName|locale_it-IT_ProductName|locale_nl-NL_ProductName|locale_fr-FR_ProductName|locale_en-GB_ProductName|locale_da-DA_ProductName|locale_cs-CZ_ProductName|locale_sv-SE_ProductName|locale_pl-PL_ProductName|locale_sk-SK_ProductName|ProductType|ProduktLink|OnlineAvailability|ProductNumber|IsProdukt|TerritoryAvailability|Category|SubCategory|ImageLink|Status|Flag0|Flag1|Flag2
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|Y|17|18|19|20|21|22|23|24|25|26
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|N|17|18|19|20|21|22|23|24|25|26
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|N|17|18|19|20|21|22|23|24|25|26
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|Y|17|18|19|20|21|22|23|24|25|26
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|Y|17|18|19|20|21|22|23|24|25|26
我只想排除在第16个参数中有N的所有行。因此,我提出了一个正则表达式模式,它可以做到这一点:

^([^|]*\|){16}N
演示RegEx可以在线工作

当我尝试将此功能用于findstr时,如下所示:

FINDSTR /V "^([^|]*\|){16}N" H:\BatchTest\LineProcessing\myfile.txt >H:\BatchTest\LineProcessing\result.txt
pause
exit
我总是得到完整的文件,而且似乎没有使用正则表达式。有人能给我指出正确的方向,让我找出我的错误吗?我试图通过这篇文章获得更多的信息,但我找不到我的缺陷,也没有发现它


感谢任何帮助

从批处理中将powershell作为工具调用:

@Echo off
Set "FileIn=H:\BatchTest\LineProcessing\myfile.txt"
Set "FileOut=H:\BatchTest\LineProcessing\result.txt"
powershell -NoP -C "Get-Content '%FileIn%' |Where-Object {$_ -notmatch '^([^|]*\|){16}N'}"  >"%FileOut%"
pause
exit
在powershell中使用别名可以缩短命令

powershell -NoP -C "gc '%FileIn%'|?{$_ -notmatch '^([^|]*\|){16}N'}"  >"%FileOut%"
根据,findstr对正则表达式的支持非常有限

您可能想尝试以下方法:

FINDSTR /V "^([^|]*\|){16}N" H:\BatchTest\LineProcessing\myfile.txt >H:\BatchTest\LineProcessing\result.txt
pause
exit
在第三方的第五方方/V V^^^(猪猪124四四四四四四四四四方方方/V^^//////V^^////V^^^//第四四四四四四四四四四四四四四四四四四四四四四方方方方///五五五五五五五五五五五五五五/////四四四四四四四四四四四四四四四四方方方方方//////////五五五五五五五五五五五五五五五五///////////////////五五五五五五五五五五五五////////////////////////////五五五/////////////////////////////.txt 但不幸的是,这会导致一个错误FINDSTR:Search string太长。因为指定的字符类[]太多,我想请参考您在问题中已经引用的有用线程:

然而,我可以想到一种解决方法,使用a读取文件并删除感兴趣的列之前的所有16列;仅当前面的列均为空时,此选项才起作用:

@回音 设置头=&设置标志= 对于/F usebackq令牌=1-16*delims=| eol=|%%A in%~1 do 如果未定义头 设置头=&设置标志= 其他的 设置行=%%Q cmd/V/C echo!行!|>nul findstr ^N | | |设置标志= 如果定义了标志 回音%%A^ |%%B^ |%%C^ |%%D^ |%%E^ |%%F^ |%%G^ |%%H^ |%%I^ |%%J^ |%%K^ |%%L^ |%%M^ |%%N^ |%%O^ |%%P^%Q 设旗= 这使得有趣的列显示为第一列,因此现在可以使用findstr

或者这里有另一种根本不使用findstr的方法:

@回音 设置头=&设置标志= 对于/F usebackq令牌=1-17*delims=| eol=|%%A in%~1 do 如果未定义头 设置头=&设置标志= 其他的 如果不是%%Q==N设置标志= 如果定义了标志 回音%%A^ |%%B^ |%%C^ |%%D^ |%%E^ |%%F^ |%%G^ |%%H^ |%%I^ |%%J^ |%%K^ |%%L^ |%%M^ |%%N^ |%%O^ |%%P^%Q^% 设旗= 如果任何列可能为空,则可以使用以下改编代码:

@回音 设定线= 对于/F usebackq^delims^=^eol^=%%L in%~1 do 如果未定义行 设置行=%%L 回声%%L 其他的 设置行=%%L setlocal EnableDelayedExpansion 对于/F令牌=17 delims=| eol=|%%K in |!行:|=| |!做 端部 设置项=%%K setlocal EnableDelayedExpansion 如果不是!物品:~1==N回声!线 端部 在提取值并将其与N进行核对之前,会在每个项目前面加一个下划线,这样for/F就不会出现空列。

用户aschipfl有。使用FINDSTR没有简单的解决方案

你可以用我的方法轻松地解决这个问题。JREPL是纯脚本混合JScript/批处理,从XP开始在任何Windows计算机上本机运行-不需要第三方exe文件

在命令行中,您可以简单地使用:

jrepl "^([^|]*\|){16}(?!N\|)" "" /k 0 /f myfile.txt /o result.txt
在批处理文件中,您需要使用CALL,不幸的是,这将使引号^加倍。添加了\XSEQ,以便可以使用扩展转义序列\c代替^

上述解决方案仅保留至少有17列且没有N列作为第17列的行;这意味着它将排除没有17列的行

如果您想使用最初的策略,简单地排除以N作为第17列的行,那么

jrepl "" "" /exc "/^([^|]*\|){16}N\|/" /k 0 /f myfile.txt /o result.txt


/XSEQ不是必需的,因为/EXC regex自动支持扩展转义序列。

为了补充我先前的评论并与现有PowerShell答案一起使用,这里有一个批处理文件行,它使用PowerShell,但不需要执行regex

它以管道分隔的csv形式读取文件,并输出其OnlineAvailability字段与Y匹配的行,可以修改为-NotMatch“N”:

@PowerShell-NoP IpCSV'H:\BatchTest\LineProcessing\myfile.txt'-Del'|'|?{$|.OnlineAvailability-Match'Y'}EpCSV'H:\BatchTest\LineProcessing\result.txt'-NoT-Del'|' 结果应该是格式正确的csv,带有双引号字段

如果您不希望使用这些双引号字段,则此修改可能是合适的:

@PowerShell-NoP IpCSV'H:\BatchTest\LineProcessing\myfile.txt'-Del'|'|?{$|.OnlineAvailability-Match'Y'}}转换为CSV-NoT-Del'|'|%{$|-Replace'',}输出文件'H:\BatchTest\LineProcessing\result.txt' 见
findstr/的帮助?或者访问以了解findstr的正则表达式功能相当有限。我建议切换到PowerShell根据,findstr只支持正则表达式的一小部分…我之前阅读了这两个链接,不幸的是,我不确定我的表达式不支持正则表达式的哪个部分。是{16}部分吗?因为从我的角度来看,其他一切都在文档中。我不能切换到powershell,因为调用程序只会执行批处理文件。findstr只支持*量词,甚至不支持+。powershell只是一个可执行文件,其方式与findstr基本相同,因此没有明显的原因说明为什么不能直接从批处理文件调用它,并从其正则表达式中获益。事实上,也可以使用PowerShell将文件读取为管道分隔的csv,并排除第16个字段不匹配的行,这也可以从批处理文件中调用!
call jrepl "" "" /exc "/\c([\c|]*\|){16}N\|/" /k 0 /f myfile.txt /o result.txt