2015-07-09 7 views
4

У меня есть .txt-документ с более чем 32 000 строк прокомментированного машинного кода. Это выглядит следующим образом:Пакетный файл для удаления первых 18 символов из 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 символов должны быть удалены, включая вкладки.
  • В противном случае это название функции, поэтому добавьте полуколону с последующим пробелом в начале (не обязательно).

Любая помощь будет принята с благодарностью.

+0

Сильное предложение: используйте «настоящий язык» - не файл .bat! Возможно, вы можете сделать это с помощью .bat-файла ... так же, как вы, вероятно, можете есть стручковые бобы через нос вместо своего рта. Это просто не рекомендуется;) ПРЕДЛОЖЕНИЕ: Возможно, [сценарий Powershell] (http://windows-powershell-scripts.blogspot.com/2009/06/awk-equivalent-in-windows-powershell.html)? – paulsm4

+0

Это также можно сделать очень легко в [java] (http://stackoverflow.com/tags/java/info). Дайте мне знать, если вы выберете этот язык, и я буду рад помочь: D – UnknownOctopus

+0

К сожалению, я еще не знаком с каким-либо другим языком. Если вы можете предоставить код для другого языка и который может быть легко преобразован в исполняемый файл любого типа, я с радостью соглашусь с этим предложением. : P –

ответ

2

Пакетный файл ниже другой подход, который может работать быстрее, чем другие подобные методы, но это во многом зависит от размера файл:

@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:""})); 
+0

Ничего себе, этот второй вариант действительно очень быстрый и работает так же хорошо, как и другие решения, которые я пробовал. (Кстати, мой документ - 1,5 МБ.) Не могли бы вы изменить свой код, чтобы я мог перетащить .txt-файл в файл .bat для создания нового файла с внесенными изменениями? –

2

Итак, следующий код (это в java btw) будет читать текст из файла, который вы предоставляете, обрабатывать его, и если строка начинается с C3/, будет напечатана строка с первыми 18 символами, а пробел в начале и конце обрезается. Если линия не начинается с C3/, тогда строка будет напечатана как есть. (FYI это 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.txt и OriginalFileName.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 
+0

Я чувствую себя рывком, чтобы тратить ваше время, но в итоге я получил пакетный файл, который я искал , поэтому я не буду загружать Java ... на данный момент по крайней мере. : P Вероятно, я посмотрю на C или C++, когда у меня есть время. Надеюсь, кто-то там найдет использование для кода, который вы опубликовали. –

+0

Все в порядке, мне не пришлось так долго заниматься. Я рад, что у вас есть более легкое решение :). – UnknownOctopus

1

Этот пакетный файл должен соответствовать вашим требованиям. Просто сохраните его как whatever.cmd и запустите его с помощью whatever.cmd file_to_process. Сохраните вывод, перенаправляя stdout, например whatever.cmd file_to_process > 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.

+0

Спасибо. Ваш исходный код не работал, но отредактированный работал отлично. –

1

Я обычно использую JREPL.BAT для изменения текста регулярного выражения в командной строке Windows.

JREPL.BAT - это чистая скриптовая (гибридная JScript/пакетная) утилита, которая запускается изначально на любом компьютере Windows с XP. Полная документация встроена в скрипт.

Единственная строка - это все, что необходимо для вашей проблемы. Предположим, что ваш файл является «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 
+0

Большое спасибо, это сработало отлично. Вы, ребята, спасли мне по крайней мере дюжину часов повторяющейся работы. Я сравнивал вывод с тем, который был создан с помощью кода jeb, а ваши обрезанные конечные пробелы, что может или не может быть хорошим в зависимости от контекста. –

+0

@ SheldonM.- Решение JREPL не будет разделять пробелы. Я забыл упомянуть, что пакетное решение разделит контрольные символы (включая вкладки). Но он не разделяет конечные пробелы. Не проблема для вашего приложения, но пакетное решение также ограничено 1021 символом в строке. – dbenham

+0

О, ты прав, они тянулись за табу. Сожалею. –

2

Использование регулярных выражений замены будет решить вашу проблему в одной строке:

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

Это конечно, предполагает, что у вас есть sed. Я сделал это в linux, и содержимое test.txt было заменено по мере необходимости.

Вы можете попробовать окна версию СЭД с этого сайта:

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

+0

Спасибо за ваше время, но у меня нет sed, и в итоге я получил простое пакетное решение, на которое я надеялся. –

+0

Добро пожаловать. Я ценю ваш ответ, но, думаю, не стоит беспокоиться об объяснениях в StackOverflow. Из вышеперечисленного, похоже, полезно для других. –

Смежные вопросы