【问题标题】:Batch file to remove first 18 chars from txt file从 txt 文件中删除前 18 个字符的批处理文件
【发布时间】:2015-07-09 01:26:10
【问题描述】:

我有一个包含超过 32,000 行注释机器代码的 .txt 文档。它看起来像这样:

Display menu window
C0/000E:    E220        SEP #$20
C0/0010:    C210        REP #$10
C0/0012:    20640B      JSR $0B64
C0/0015:    20750B      JSR $0B75
C0/0018:    C220        REP #$20
C0/001A:    A90001      LDA #$0100

出于编译目的,我需要将代码转换如下:

; Display menu window
SEP #$20
REP #$10
JSR $0B64
JSR $0B75
REP #$20
LDA #$0100

具体来说,这意味着:

  • 空白行必须保持不变。
  • 如果一行以“C0/”开头,则前 18 个字符将被删除,包括制表符。
  • 否则,它是一个函数标题,所以在开头添加一个分号,后跟一个空格(不是强制性的)。

任何帮助将不胜感激。

【问题讨论】:

  • 强烈建议:使用“真实语言”——而不是 .bat 文件!您可能可以使用 .bat 文件来做到这一点……就像您可以通过鼻子而不是嘴巴吃四季豆一样。只是不推荐;)建议:也许是Powershell script
  • 这也可以在java 中轻松完成。如果您选择这种语言,请告诉我,我很乐意为您提供帮助:D
  • 很遗憾,我还不熟悉任何其他语言。如果您可以提供不同语言的代码并且可以轻松转换为任何类型的可执行文件,那么我将很乐意接受该建议。 :P
  • @SheldonM。为了运行java代码,你需要安装JDK。但是,我可以提供 Java 程序的代码来执行您的要求。就像我说的,你需要安装JDK,这样你才能编译和运行程序。
  • 如果需要我可以下载JDK。但是您必须将每个“C0/”检查替换为“C3/”。 (抱歉,出于隐私原因,我提供了错误的值,我打算自己更改 BAT 代码。)

标签: java windows batch-file


【解决方案1】:

下面的批处理文件是一种不同的方法,可能比其他类似方法运行得更快,但这在很大程度上取决于文件的大小:

@echo off

for /F "tokens=1-2*" %%a in ('findstr /N "^" test.txt') do (
   for /F "tokens=1,2 delims=:/" %%d in ("%%a") do (
      if "%%e" equ "C3" (
         echo %%c
      ) else if "%%e" neq "" (
         echo ; %%e %%b %%c
      ) else (
         echo/
      )
   )
)

但是,最快的方法是通过 Batch-JScript 混合脚本。使用 .bat 扩展名保存以下文件:

@set @Batch=1    /*
@cscript //nologo //E:JScript "%~F0" < test.txt
@goto :EOF & rem */

WScript.Stdout.Write(WScript.Stdin.ReadAll().replace
   (/^C3\/.{15}|^(..)/gm,function(A){return A.length==2?"; "+A:""}));

【讨论】:

  • 哇,第二个选项确实非常快,并且与我尝试过的其他解决方案一样有效。 (顺便说一下,我的文档是 1.5 MB。)您介意修改您的代码,以便我可以将 .txt 文件拖放到 .bat 文件上以生成应用修改的新文件吗?
【解决方案2】:

因此,以下代码(这是在 java 中顺便说一句)将从您提供的文件中读取文本,对其进行处理,如果该行以 C3/ 开头,将打印删除前 18 个字符的行,并且开头和结尾的空白被修剪掉了。如果该行不以C3/ 开头,则该行将按原样打印。 (仅供参考,在处理巨大的文本文件方面,这个 java 代码可能比批处理文件更快,这就是我首先推荐 java 的原因:P)

import java.io.*;


public class ClassName{
    public static void main(String args[])throws IOException{
        PrintWriter file_out = new PrintWriter("OutputFileName.txt");
        BufferedReader br = new BufferedReader(new FileReader("OriginalFileName.txt"));

        String line, temp, out = "";
        while((line = br.readLine()) != null){
            temp = line.substring(0,3);
            if(temp.equals("C3/")){
                out = line.substring(18, line.length()).trim();

                file_out.println(out);

            }else{
                file_out.println(line);
            }



        }
        file_out.close();
    }

}

当然用您的文本文件替换OutputFileName.txtOriginalFileName.txt。要编译和运行它,您需要安装和设置JDK。要了解如何做到这一点,click here。您还可以在网上找到许多其他关于如何设置和使用 JDK 的教程。设置 JDK 后,将此代码保存为 ClassName.java,编译并运行它。确保该程序与您的输入/输出文件保存在同一文件夹中。

注意:通常我不会给出这样的代码,但我很无聊,感觉很好:)

另外,我强烈建议您尝试自己使用 java 编程。这是一种非常有趣且用途广泛的语言。如果您有任何其他问题,请随时告诉我们:D。

示例输入:

Display menu window
C3/000E:    E220        SEP #$20
C3/0010:    C210        REP #$10
C3/0012:    20640B      JSR $0B64
C3/0015:    20750B      JSR $0B75
C3/0018:    C220        REP #$20
C3/001A:    A90001      LDA #$0100

示例输出:

Display menu window
SEP #$20
REP #$10
JSR $0B64
JSR $0B75
REP #$20
LDA #$0100

【讨论】:

  • 我觉得浪费你的时间是个混蛋,但我最终得到了我正在寻找的批处理文件,所以我不会费心下载 Java ......至少现在。 :P 不过,如果有时间,我可能会研究 C 或 C++。希望有人会发现您发布的代码的用途。
  • 没关系,没花那么长时间。我很高兴你有一个更简单的解决方案:)。
【解决方案3】:

使用正则表达式替换将在单行中解决您的问题:

sed -i -- 's/C0\/.....................//g' <your_file_name>

这当然假设你已经 sed。我在 linux 中做了这个,test.txt 的内容被你需要的替换了。

您可以从这个站点尝试 Windows 版本的 sed:

http://gnuwin32.sourceforge.net/packages/sed.htm

【讨论】:

  • 感谢您的宝贵时间,但我没有 sed,最终得到了我希望的简单批处理文件解决方案。
  • 不客气。我非常感谢您的回复,但我认为不必费心在 StackOverflow 上进行解释。从上面的赞成票看来,它对其他人有用。
【解决方案4】:

这个批处理文件应该满足您的要求。只需将其保存为 whatever.cmd 并使用whatever.cmd file_to_process 运行它。通过重定向标准输出来保存输出,例如whatever.cmd file_to_process &gt; processed_file

@echo off
set "DEL_TOKEN=C0/"
set "DEL_TOKEN_LEN=3"
set "CHARS_TO_REMOVE=18"
set "FILENAME=%~1"

SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ %FILENAME%"`) do (
    set "LINE=%%a"
    SETLOCAL EnableDelayedExpansion
    set "LINE=!LINE:*:=!"
    if not "!LINE!"=="" (
        if "!LINE:~0,%DEL_TOKEN_LEN%!"=="%DEL_TOKEN%" (
            set "LINE=!LINE:~%CHARS_TO_REMOVE%!"
        ) else (
            set "LINE=; !LINE!"
        )
    )
    echo(!LINE!
    ENDLOCAL
)

jeb 提供的线路阅读器。

【讨论】:

  • 谢谢。您的原始代码不起作用,但编辑后的代码运行良好。
【解决方案5】:

我一般使用JREPL.BAT在Windows命令行中做正则表达式文本修改。

JREPL.BAT 是一个纯脚本(混合 JScript/批处理)实用程序,可在从 XP 开始的任何 Windows 机器上本地运行。完整的文档嵌入在脚本中。

只需一行即可解决您的问题。假设你的文件是“test.in”,你的输出是“test.out”,那么:

jrepl "^C0/.{15}|^." "|; $&" /t "|" /f test.in /o test.out

如果您想覆盖原始文件,请改用/o -

JREPL 解决方案非常快。

如果您想要纯批处理,那么您可以使用以下优化解决方案:

@echo off
setlocal enableDelayedExpansion
for /f %%N in ('find /c /v "" ^<test.txt') do set "cnt=%%N"
<test.in >test.out (
  for /l %%N in (1 1 %cnt%) do (
    set "ln="
    set /p "ln="
    if "!ln:~0,3!" == "C0/" (set "ln=!ln:~18!") else if defined ln set "ln=; !ln!"
    echo(!ln!
  )
)

如果你想覆盖原来的,那么在最后添加下面一行:

move /y test.out test.in >nul

【讨论】:

  • 非常感谢,这非常有效。你们为我节省了至少十几个小时的重复工作。我将输出与使用 jeb 的代码创建的输出进行了比较,您的输出修剪了尾随空格,这取决于上下文可能是也可能不是一件好事。
  • @SheldonM.- JREPL 解决方案不会去除尾随空格。我忘了提到批处理解决方案将去除尾随控制字符(包括制表符)。但它不会去除尾随空格。对您的应用程序来说不是问题,但批处理解决方案也被限制为每行 1021 个字符。
猜你喜欢
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多