2

I'm trying to write a batch file that will look at every character in a small text file (a CUE sheet, actually) and do three things -- remove all question marks, replace any slash marks with a hyphen and replace colons with two hyphens -- as per the second line in the example below.

  TRACK 01 AUDIO
    TITLE "Colon:  Slash / Question Mark?"
(would be changed to)
    TITLE "Colon -- Slash - Question Mark"

I know how to use findstr to copy the lines containing those characters to a new text file (but only those lines), and not how to do the search-and-replace. And findstr also has the unwanted consequence of removing leading spaces, which I wish to retain. Not sure what's the right approach here. (I should add that for various reasons I prefer not to use a third-party utility.)

Wally Walters
  • 75
  • 1
  • 1
  • 8
  • 1
    It should be possible in principle, but perhaps 3rd party utilities like GNU SED would be more suited to the task. – Magoo Feb 27 '17 at 09:57
  • 1
    @Magoo check the answer below it works without 3rd Party (considering PowerShell shipped with Windows) – Baljeetsingh Sucharia Feb 27 '17 at 10:11
  • 1
    In your example you are not replacing a colon with two hypens, but with _a space_ and two hypens. `findstr` did _not_ remove leading spaces. – Aacini Feb 27 '17 at 15:16
  • Thanks, AAcini. You're right about the space and two hyphens, but FINDSTR also removes the leading spaces at the start of the line (in front of "Track" and "Title"), which is more what I was concerned about. But Magoo's solution should take care of those. – Wally Walters Feb 27 '17 at 16:54

2 Answers2

7

You can use Powershell to solve this very easily.

Open PowerShell and type this

(Get-Content C:\Users\Admin\StackOverflow\some.txt).Replace(":"," - -") | Set-Content C:\Users\Admin\StackOverflow\SomeModified.txt

Basically,

Get-Content will open the file.

.Replace to replace the text(old text, new text)

| Set-Content < path > to output on diffrent file.

Screenshots Source File Powershell Command Destination File Post Change

Baljeetsingh Sucharia
  • 1,990
  • 1
  • 19
  • 37
  • 1
    Thanks, Baljeetsingh, but my batch file has to be backwards-compatible with Windows PCs that don't have .Net Framework -- thus, no Powershell. I really need to figure out how to write this in Windows batch. – Wally Walters Feb 27 '17 at 10:55
  • Some environments don't allow PowerShell scripts to run – Chad Lehman Feb 03 '20 at 15:22
  • @ChadLehman yes I understand that not every tech is available on every platform. We can take advantage where every applicable. For that matter bat file works only on windows. – Baljeetsingh Sucharia Feb 19 '20 at 05:18
7
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q42482508.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 SET "line=%%a"
 SET "line=!line:?=!"
 SET "line=!line:/=-!"
 SET "line=!line::=--!"
 ECHO !line!
)
)>"%outfile%"

GOTO :EOF

You would need to change the settings of sourcedir and destdir to suit your circumstances.

I used a file named q42482508.txt containing your data for my testing.

Produces the file defined as %outfile%

Invoke delayed expansion to allow strings to be manipulated in a code block.

Read each line of the file to %%a thence line; replace each ? with nothing, / with one - and : with two, and echo the result.

Parenthesising the for allows redirection to the specified file.

The pattern is set "var1=!var2:stringtoreplace=replacementstring!" as documented, ! in place of % to use delayedexpansion.

Note that your text specifies the replacemnt string for : as -- whereas your example shows it being replaced by "Space--"

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Thanks, Magoo. I was not aware of this powerful feature of the SET command, and had been trying to use FOR loops to iterate through each character on every line, without success. – Wally Walters Feb 27 '17 at 16:52
  • Speaking of which, is there a way to make your FOR block skip any line beginning with the word "INDEX?" – Wally Walters Feb 27 '17 at 17:35
  • 2
    Certainly. Replace `"%filename1%"` with `'findstr /v /L /i /b /c:"INDEX?" "%filename1%"'` and remove the `usebackq`. `usebackq` instructs that a double-quoted string be interpreted as a filename, not a string (in case of spaces in the filename). The `findstr` command **must** be single-quoted and means `/v` lines that do not match `/L` literally `/i` case-insensitive (if required) `/b` beginning `/c:"characterstringtomatch"`. See `findstr /?` from the prompt for more info. – Magoo Feb 27 '17 at 22:34
  • Thanks again, Magoo. Man, how do you guys keep all the commands and options and switches, rules and limitations and feature sets, and quirks and bugs and workarounds straight? I consider myself reasonably bright but find myself frequently tripping over all the little complexities. Very grateful for your guidance. – Wally Walters Feb 28 '17 at 00:05
  • Seems I'm still missing something. If the first three lines of my input are `TRACK 01 AUDIO` `TITLE "This Title Has a Question Mark?"` and `INDEX 01 04:36:52` the corresponding output now is `TRACK` `TITLE` and `INDEX` when all I'm trying to do is get it to ignore the colons in the line beginning with "INDEX." – Wally Walters Mar 01 '17 at 10:21
  • Figured it out. FINDSTR was the solution, but I needed to do something more like this `for /f "usebackqdelims=" %%a in ("%FILE%") do (` `set "LINE=%%a"` `echo !LINE! | findstr /i /c:"INDEX" > nul & if errorlevel 1 (` inside an IF block before echoing the %LINE%. – Wally Walters Mar 01 '17 at 10:51