BATCH文件在多个.txt文件中复制特定文本并在X之后过去

时间:2018-04-11 22:34:49

标签: batch-file cmd

我开始学习批处理文件命令,我成功地创建了一些基本脚本来简化工作中的一些任务。 现在我正在寻找自动化重复性任务,需要花费大量时间才能完成......并且说我每天都要手动完成: 我有一堆.txt文件分组在同一个文件夹中,这些texte文件的内容如下所示:

评论专栏

START (电子元件名称)(引脚数)

计划正文第1行

计划机构第2行

计划正文行X

结束

评论专栏

我正在做的是复制电子部件的名称"我正在努力  并在END之后粘贴它。这是一个例子:

START BC547 3

计划正文第1行

计划机构第2行

计划正文行X

结束 BC547

同一个文件中有很多空白END,你可以想象每天手动填写200到300个文本文件......

在某些情况下,结构会变为:

评论专栏

START (name1)(引脚数)

评论专栏

START (子电路1)(引脚数)

计划正文第1行

计划正文行X

结束(子电路1)

评论专栏

START (子电路2)(引脚数)

计划正文第1行

计划正文行X

结束(子电路2)

评论专栏

START (subcircuitx)(引脚数)

计划正文第1行

计划正文行X

结束(subcircuitx)

评论专栏

结束(name1)

评论专栏

如果有人可以在START之后制作批量代码来复制完整的下一个单词并将其粘贴到下面的下一个END中,我将非常感激。当STAR语法连续时,脚本必须能够检测第二种情况。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

社区已经确定,要求de novo代码满足一系列业务要求的开放式问题超出了StackOverflow 问题的范围。但我很无聊,无法帮助自己。

该算法相当紧张。迭代源文件的所有行。如果该行以START开头,则解析出ID并将值推送到堆栈(数组)上。如果该行以END开头,则将最后一个堆栈值附加到该行并弹出堆栈。如果该行不以END开头,则只需写入原始行。

但批量中没有什么是简单的。

  • FOR / F忽略空行,因此FINDSTR / N用于为每行添加行号,后跟冒号。在循环内执行字符串操作以去除行号前缀。
  • Batch没有对数组的正式支持,但代码显示了如何模拟数组。
  • 在带括号的代码块中需要延迟扩展,因此可能无法将数组成员作为!ID.%i%进行访问。该代码显示了如何将当前i值转移到FOR变量,以便您可以使用!ID.%%I
  • 延迟扩展在循环内切换为ON和OFF,以保护源文件中可能存在的任何!
  • 您无法写入您正在阅读的文件。因此必须将结果写入临时的新文件,稍后MOVEd将替换原始文件。

应使用一个或多个文件掩码调用下面的脚本,这些掩码指定应处理哪些文件。如果脚本名为“fixEnd.bat”,则fixEnd test.txt将处理当前目录中的test.txt。 fixEnd "c:\somePath\*.txt"将处理“c:\ somePath”文件夹中的所有.txt文件。 fixEnd file1.txt file2.txt将处理当前目录中的这两个文件。

@echo off
setlocal disableDelayedExpansion
for %%F in (%*) do (
  set /a i=0
  set "ID.0="
  >"%%F.new" (
    for /f "delims=" %%L in ('findstr /n "^" "test.txt"') do for /f "tokens=1,2,3 delims=: " %%A in ("%%L") do (
      if "%%B" == "START" (
        set /a i+=1
        setlocal enableDelayedExpansion
        for %%I in (!i!) do (
          endlocal
          set "ID.%%I=%%C"
        )
      )
      if "%%B" == "END" (
        setlocal enableDelayedExpansion
        for %%I in (!i!) do (
          (echo END !ID.%%I!)
          endlocal
          set "ID.%%I="
          set /a "1/i, i-=1)" 2>nul %= division by zero error prevents negative i values =%
        )
      ) else (
        set "ln=%%L"
        setlocal enableDelayedExpansion
        (echo(!ln:*:=!)
        endlocal
      )
    )
  )
  move /y "%%~F.new" "%%F" >nul
)

尽管我喜欢使用批处理的挑战,但我很久以前得出的结论是,除了非常简单的情况外,使用纯批处理文本文件是不切实际的。在许多情况下,批量只是不能完成任务。这就是我编写JREPL.BAT的原因,这是一个正则表达式文本处理实用程序,它是纯脚本(混合JScript /批处理),可以在XP以后的任何Windows机器上本机运行。

JREPL拥有无数的选项,可以提供强大的功能,尤其是在命令行中集成用户提供的JScript的能力。使用JREPL,相同的算法以更直接的方式实现,并且代码 比纯批处理更快:

@echo off
for %%F in (%*) do for %%F in (test.txt) do call jrepl^
  "^START\b\s*(\S*)/^END\b.*"^
  "id[id.length]=$2;$txt=$0/$txt='END '+(id.length?id[id.length-1]:'');id=id.slice(0,-1)"^
  /jbeg "var i=0, id=[]" /t "/" /jq /f "%%F" /o -

使用命令行中的jrepl /??查看整个文档,一次一个屏幕。 jrepl /?help列出了所有可用的帮助类型。 jrepl /?options简要概述了所有可用选项。 jrepl /?/t会显示/T选项的帮助。等