1

I deal with a large text files daily, I need to add a single "-" to each line 8 characters in for instance :

ABCDEF DC01 B738
ABCDEF      B787

would become

ABCDEF -DC01 B738
ABCDEF -     B787

How easy is this to do with a batch file?

regards David

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • 1
    Read http://ss64.com/nt/syntax-substring.html then [edit] your question and share a [mcve] where you stuck in. – JosefZ Jan 16 '17 at 14:37
  • 3
    As answer to your question: it is very easy to do this with a Batch file! **`;)`** – Aacini Jan 16 '17 at 15:14
  • @Stephan: How do you justify your edits to the question? You seem to have added additional scenarios that were not in the original question. – abelenky Jan 16 '17 at 16:31
  • @abelenky: see [revision](http://stackoverflow.com/posts/41678290/revisions) - check "side-by-side markdown" – Stephan Jan 16 '17 at 16:36
  • I see your mark down. You added a new scenario that did not exist in David's original question. Why? – abelenky Jan 16 '17 at 16:37
  • it did exist - but we could not see it because of bad formatting. You can clearly see it with "side-by-side-markdown". I only fixed formatting - there was no change to the data. – Stephan Jan 16 '17 at 16:40
  • (@abelenky: sorry, that it invalidates your answer - which was fine for the original formatted question) – Stephan Jan 16 '17 at 16:44

3 Answers3

1
@echo off
setlocal enabledelayedexpansion

(for /f "delims=" %%a in (input.txt) do (
  set line=%%a
  set line=!line:~0,7!-!line:~7!
  echo !line!
))>output.txt

Note: this will remove empty lines and has problems with exclamation marks. (may or may not be a problem; depends on your file content)
It also will eliminate lines that begin with ; due to default EOL character.
Also, lines are limited to ~8190 bytes max length (Thanks dbenham)

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Why a single redirect to `output.txt`, rather than append each `echo !line!` to `output.txt`? – abelenky Jan 16 '17 at 16:51
  • 1
    because it is [much faster](http://stackoverflow.com/a/39453678/2152082) - especially with large files (like the question states). – Stephan Jan 16 '17 at 16:57
  • I'm also concerned it consumes a lot of memory, assembling all the output in mem. – abelenky Jan 16 '17 at 17:01
  • 2
    well, it doesn't collect all the data in memory before writing it. Instead, it opens the file, writes what is to write (without closing the file) until there is no more data. *Then* the file is closed. (you can check, by typing the file while it's getting written (you may want to add a `timeout -t 1` into the loop to get enough time to do so)) – Stephan Jan 16 '17 at 17:05
  • Another limitation - this will eliminate lines that begin with `;` due to default EOL character. Also, lines are limited to ~8190 bytes max length.. – dbenham Jan 16 '17 at 21:21
  • Hi - this is exactly what I need. thank you, the lines I have wont have exclaimation marks in them so this should work perfectly. – David Cummings Jan 17 '17 at 10:36
0

Here is a "robust" pure batch solution that preserves ! and empty lines. But it is still limited to ~8190 max line length, and it is painfully slow for large files. This will not modify lines that have less than 7 characters.

@echo off
setlocal disableDelayedExpansion
set "file=file.txt"

>"%file%.new" (
  for /f "delims=" %%A in ('findstr /n "^"` "file.txt"') do (
    set "s=%%A"
    setlocal enableDelayedExpansion
    set "s=!s:*:=!"
    if not defined s (
      echo(
    ) else if "!s:~7!" equ "" (
      echo(!s!
    else (
      echo(!s:~0,7!-!s:~7!
    )
    endlocal
  )
)
move /y "%file%.new" "%file%" >nul

And here is a truly robust and fast solution that uses JREPL.BAT - a regular text processing utility that is pure script (batch/JScript) that runs natively on any Windows machine from XP onward - no 3rd party executable required. This solution also does not modify lines that have fewer than 7 characters.

From the command line:

jrepl "^.{7}" "$&-" /f file.txt /o -

From within a batch script

call jrepl "^.{7}" "$&-" /f file.txt /o -
dbenham
  • 127,446
  • 28
  • 251
  • 390
0

This is a simple two-lines Batch-JScript hybrid script solution that have all the advantages of JScript language: is fast, robust, manage all special characters and preserve empty lines. Besides, it is simple enough to be understood and then modified for other similar tasks after read the documentation. Copy it to a file with .BAT extension.

@set @a=0 // & cscript //nologo //E:JScript "%~F0" < input.txt > output.txt & goto :EOF

WScript.Stdout.Write(WScript.Stdin.ReadAll().replace(/^.{7}/gm,"$&-"));
Aacini
  • 65,180
  • 12
  • 72
  • 108