如何在批处理脚本中基于一组标题,详细信息等拆分文件?

时间:2017-08-24 03:26:04

标签: windows batch-file

我有一个如下所示的文件。

File Date Source Target                     
HD|Field1|Field2|Field3  
ITEM1|Other fields1  
ITEM2|Other fields2  
HD|Field1|Field2|Field3  
ITEM1|Other fields  
ITEM2|Other fields  
ITEM3|Other fields

我需要根据HD的出现创建单独的文件。第一个文件将包含从HD开始的行,并将包含所有内容,直到下一个HD段开始。

可以有N个HD段。还需要根据HD段的Field1值重命名文件。

因此文件1将作为File-Field1并包含

HD|Field1|Field2|Field3  
ITEM1|Other fields1  
ITEM2|Other fields2  

文件2将是File-Field1(第二个HD段),并包含

HD|Field1|Field2|Field3  
ITEM1|Other fields  
ITEM2|Other fields  
ITEM3|Other fields

我需要一些帮助来获取批处理脚本。我已经完成了一些基本代码,如下所示。

setLocal EnableDelayedExpansion 
set limit=1 
set file=Sample.txt 
set lineCounter=1 
set filenameCounter=1 
set name= 
set extension= 
for %%a in (%file%) do ( set "name=%%~na" set "extension=%%~xa" ) 
for /f "skip=1 delims=," %%a in (%file%) do ( set 
splitFile=Load-!name!!filenameCounter!!extension! 
if "%%a"=="HD|" ( set /a filenameCounter=!filenameCounter! + 1 set 
lineCounter=1 echo Created !splitFile!. ) echo %%a>> !splitFile! set /a 
lineCounter=!lineCounter! + 1 ) 

有了这个我只得到1个文件和HD |但是这个名字可以用作Load-Sample1.txt。然而,数据丢失很大。我尝试的是做一个循环,跳过第一行,然后在for循环中每次创建一个新的文件HD |遇到了。

1 个答案:

答案 0 :(得分:2)

这是一个脆弱的纯批处理解决方案(代码可以根据源文件的内容破解的方式很多)

@echo off
setlocal enableDelayedExpansion
set "outfile="
for /f "delims=" %%A in (sample.txt) do (
  for /f "delims=| tokens=1,2" %%a in ("%%A") do if "%%a"=="HD" set "outfile=%%b"
  if defined outfile echo(%%A>>"!outfile!"
)

以上是上述代码失败的一些方法:

  • 将删除空行
  • ;开头的行将被删除
  • 包含!的行将损坏

代码可以变得更加健壮,但它会变得更加复杂。我不打扰。除最简单的任务外,纯批处理是文本文件操作的可怕语言。它很慢,需要大量的晦涩知识。

added a new feature (v6.8)JREPL.BAT regular expression text processor {{3}},这使得为这个问题创建快速而强大的解决方案变得微不足道。

JREPL.BAT是纯脚本(混合JScript /批处理),可以在任何Windows机器上从XP开始本地运行 - 不需要第三方exe文件。

我使用正则表达式来定位HD行并提取文件名。我使用自定义JScript在每个HD行打开一个新的输出文件。

jrepl "^HD\|([^|]+)" "openOutput($1);$txt=$0" /jq /f "sample.txt" >nul

如果在另一个批处理脚本中使用该命令,请务必使用CALL JREPL。但是,CALL会将引用的插入符号加倍,而插入符号在技术上可能是文件名的一部分。因此,您还应该使用6.8版的另一个新功能 - 新的\c插入符转义序列。这将隐藏CALL中的插入符号,因此它不会加倍。

call jrepl "\cHD\|([\c|]+)" "openOutput($1);$txt=$0" /x /jq /f "sample.txt" >nul