如何有选择地从一系列文件中复制文本并粘贴到一个文件中?

时间:2012-05-16 03:07:22

标签: windows batch-file concatenation

我在一堆单独的文件夹中有大量同名文件。例如:
mods \ Lady Knight \ media \ units \ items \ armor
MODS \帕拉丁\媒体\ \单位项目\装甲
MODS的\巫师\媒体\单元\项目\装甲

在这些文件夹的每一个中都有例如:
a_chest_magic_04a.dat
a_chest_magic_04b.dat
a_chest_magic_04c.dat

这些.dat文件实际上只是具有不同扩展名的.txt文件。在每个文件中都有一堆文本行,这些文本在不同文件夹中的同名文件中是相同的。例如,前面几行:

mods \ Lady Knight \ media \ units \ items \ armor \ a_chest_magic_04a.dat
MODS \帕拉丁\媒体\ \单位项目\装甲\ a_chest_magic_04a.dat
MODS的\巫师\媒体\单元\项目\装甲\ a_chest_magic_04a.dat

将完全相同,但在

之间

mods \ Lady Knight \ media \ units \ items \ armor \ a_chest_magic_04a.dat mods \ Lady Knight \ media \ units \ items \ armor \ a_chest_magic_04b.dat

文字会有所不同。
但是,在每个文件的末尾都是这样的:

[WARDROBE]
<STRING>CLASS:DESTROYER
<STRING>TEXTURE:media/wardrobe/destroyer/dest_scale_chest.png
<STRING>MESH:media/wardrobe/destroyer/scale_set.mesh
<STRING>ICON:scalevest
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:ALCHEMIST
<STRING>TEXTURE:media/wardrobe/alchemist/alchemist_hvyleather_chest.png
<STRING>MESH:media/wardrobe/alchemist/hvyleather_set.mesh
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:VANQUISHER
<STRING>MESH:media/wardrobe/vanquisher/vanquisher_buckled.mesh
<STRING>TEXTURE:media/wardrobe/vanquisher/buckled_chest.png
<STRING>ICON:vanq_buckled_body
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:LADY KNIGHT
<STRING>TEXTURE:media\wardrobe\ladyknight\buckled_chest.png
<STRING>MESH:media\wardrobe\ladyknight\vanquisher_buckled.mesh
<STRING>ICON:vanq_buckled_body
[/WARDROBE]
[/UNIT]

最后一组[WARDROBE]标签之间的行在每个版本的文件中都不同。我想要做的就是将它们组合在一起,以便最后列出所有这些不同的[WARDROBE]组,以便 a_chest_magic_04a.dat 的最后一部分如下所示:

[WARDROBE]
<STRING>CLASS:DESTROYER
<STRING>TEXTURE:media/wardrobe/destroyer/dest_scale_chest.png
<STRING>MESH:media/wardrobe/destroyer/scale_set.mesh
<STRING>ICON:scalevest
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:ALCHEMIST
<STRING>TEXTURE:media/wardrobe/alchemist/alchemist_hvyleather_chest.png
<STRING>MESH:media/wardrobe/alchemist/hvyleather_set.mesh
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:VANQUISHER
<STRING>MESH:media/wardrobe/vanquisher/vanquisher_buckled.mesh
<STRING>TEXTURE:media/wardrobe/vanquisher/buckled_chest.png
<STRING>ICON:vanq_buckled_body
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:LADY KNIGHT
<STRING>TEXTURE:media\wardrobe\ladyknight\buckled_chest.png
<STRING>MESH:media\wardrobe\ladyknight\vanquisher_buckled.mesh
<STRING>ICON:vanq_buckled_body
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:PALADIN
<STRING>MESH:media/wardrobe/paladin/vanquisher_buckled.mesh
<STRING>TEXTURE:media/wardrobe/paladin/buckled_chest.png
<STRING>ICON:paladin_buckled_body
[/WARDROBE]
[WARDROBE]
<STRING>CLASS:NECROMANCER
<STRING>TEXTURE:media/wardrobe/alchemist/alchemist_hvyleather_chest.png
<STRING>MESH:media/wardrobe/alchemist/hvyleather_set.mesh
[/WARDROBE]
[/UNIT]

大约有十几个文件夹,每个文件夹包含相同150个左右文件的略有不同的副本。我可以复制其中一个文件夹作为主人的起点。最终目标是主副本(150个文件),其中包含来自每个不同文件夹的源文件的衣柜部分。我宁愿在Windows中这样做,因为过去我遇到麻烦,Windows和Linux回车不一样。

我大约一年半前在大学里有一个基本的脚本课程,但这远远高于此。我认为批处理文件的逻辑类似于

1)从每个文件的末尾删除[/ UNIT]
2)从文件的每个实例复制最后一个衣柜部分,并将其连接到主文件的末尾 3)对文件夹
中的每个文件重复上述操作 4)将[/ UNIT]添加到主文件的末尾

任何拥有一些boss脚本技能的人都可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

你的策略很好。

  1. 为了迭代您的所有文件,FOR是您的朋友。阅读HELP FOR并在命令行中尝试简单的事情

    for /r %a in (a_chest_*.dat) do @echo %a
    

    确保获得所需的所有文件

  2. 要将此代码移动到BAT文件中,您需要将%a替换为%% a。此外,您希望复制第一个文件以用作所有其余文件的种子。试试这样的事情..

    set first=
    for /r %%a in (a_chest_*.dat) do (
      echo %%a
      if .!first!==. (
        copy %%a wardrobes.txt
        set first=%%a
      ) 
    )
    
  3. 提取每个文件的最后一个WARDROBE部分有点棘手

    因为你想只提取WARDROBE部分的最后一次出现,你需要读取文件两次,第一次找到应该开始复制的行,第二次实时读取。

    FOR是你的朋友,首先找到最后一个[WARDROBE]和最后一个[/ UNIT]的行

    set linenum=0
    for /f "tokens=* delims=" %%a in (a_chest_magic_04c.dat ) do (
      set /a linenum+=1
      if %%a==[WARDROBE] set fromhere=!linenum!
      if %%a==[/UNIT] set tohere=!linenum!
    )
    

    和第二,找到那个地方并提取线

    set linenum=0
    for /f "tokens=* delims=" %%a in (a_chest_magic_04c.dat ) do (
     set /a linenum+=1
     if !linenum! geq !fromhere! (
       if !linenum! lss !tohere! (
        echo %%a
       )
     )
    )
    goto :eof
    
  4. 把我们到目前为止的作品放在一起

    @echo off
    setLocal EnableDelayedExpansion
    set first=
    for /r %%a in (*.dat) do (
      if .!first!==. (
        copy %%a wardrobes.txt
        set first=%%a
      ) else (
        (
          call :extractlastwardrobe %%a
        ) >>wardrobes.txt
      )
    )
    goto :eof
    
    :extractlastwardrobe
    set linenum=0
    for /f "tokens=* delims=" %%a in (%1) do (
      set /a linenum+=1
      if %%a==[WARDROBE] set fromhere=!linenum!
      if %%a==[/UNIT] set tohere=!linenum!
    )
    set linenum=0
    for /f "tokens=* delims=" %%a in (%1) do (
      set /a linenum+=1
      if !linenum! geq !fromhere! (
        if !linenum! lss !tohere! (
          echo %%a
        )
      )
    )
    goto :eof
    
  5. 差不多完成了。您仍然需要从种子文件中删除[/ UNIT]行,并将其添加到结果文件的末尾。我将此作为练习。