I am working in Windows 10 and I have text files resulting from another process that I want to edit using a batch file. I've shortened the example, File-1 (shown below with line numbers) for this post. They are all formatted this way, but much longer and with more sections:
1 Album 1 - 1982,,,
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
6 ('Song 1'),
7 ('Song 2'),
After each line with a string of 3 commas (lines 1 and 5) I want to insert two new lines of text from File-2 before the existing lines in File-1 (lines 2 and 6).
The two lines in File-2 to insert are:
NEW LINE 1
NEW LINE 2
The desired output would then be:
1 Album 1 - 1982,,,
2 NEW LINE 1
3 NEW LINE 2
4 ('Song 1'),
5 ('Song 2'),
6 |===================|
7 Album 2 - 1978,,,
8 NEW LINE 1
9 NEW LINE 2
10 ('Song 1'),
11 ('Song 2'),
The closest I've come so far as an experiment is a batch file (that I found and adapted) that finds the 3 commas and replaces them with 3 dots.
@echo off &setlocal
set "search=,,,"
set "replace=..."
(for /f "delims=" %%i in (a.txt) do (
set "word=%%i"
setlocal enabledelayedexpansion
set "word=!word:%search%=%replace%!"
echo(!word!
endlocal
)
)
Output of the adapted batch file to the screen:
1 Album 1 - 1982...
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978...
6 ('Song 1'),
7 ('Song 2'),
I don't need to change the commas to dots (that was just a test to see if I could make the batch file stop and do something at each instance of a unique string).
My dilemma is that I have searched for hours and can't find how to insert File-2 text in the two proper places of File-1. I've found many explanations on how to insert another file's text at one point or at the end of a first file (using the "type" command), but not at more than one specific point found from the search. Also, File-2 text might be more than two lines in the future, so that is why I want to use an external file to hold it.
All I really want to do right now is:
- Find a known string (3 commas).
- Read boilerplate text from a text file and insert it below the lines with the found strings, into the the file sitting in the batch file memory.
For testing, I am echoing this to the screen, but once I am able to get the right output, I can edit the batch file to redirect output to a file. I know there are easier ways of doing this using python or C, but it seems it should be easy to do this way with a small correction.
CodePudding user response:
You should not try to replace ,,, by ,,, line-break multi-line text from another file, rather should you, after echo(!word!, check whether the current line contains ,,, by if not "!word!"=="!word:,,,=!", and if so, just type out the other text file by type "File-2.txt", or by find /V "" < "File-2.txt" in case its contents may not be terminated with a final line-break:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "infile1=%~dp0File-1.txt"
set "infile2=%~dp0File-2.txt"
set "outfile=con"
set "search=,,,"
> "%outfile%" (
rem // The strange unquoted option string syntax disables the `eol` character:
for /F usebackq^ delims^=^ eol^= %%i in ("%infile1%") do (
set "word=%%i"
setlocal EnableDelayedExpansion
echo(!word!
rem // Try to remove search string; if result differs, search string occurred:
if not "!word!"=="!word:%search%=!" find /V "" < "!infile2!"
endlocal
)
)
endlocal
exit /B
CodePudding user response:
One way to do this in a cmd batch-file would be to use PowerShell. If you are on a supported Windows platform, PowerShell is available. This uses a regex to insert the content of another file.
powershell -NoLogo -NoProfile -Command ^
(Get-Content -Path .\afile1.txt) -replace ',,,', ^
\",,,$([Environment]::NewLine)$(Get-Content -Raw -Path .\afile2.txt)\"
Example:
C:>type afile1.txt
1 Album 1 - 1982,,,
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
6 ('Song 1'),
7 ('Song 2'),
C:>type afile2.txt
NEW LINE 1
NEW LINE 2
C:>powershell -NoLogo -NoProfile -Command ^
More? (Get-Content -Path .\afile1.txt) -replace ',,,', ^
More? \",,,$([Environment]::NewLine)$(Get-Content -Raw -Path .\afile2.txt)\"
1 Album 1 - 1982,,,
NEW LINE 1
NEW LINE 2
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
NEW LINE 1
NEW LINE 2
6 ('Song 1'),
7 ('Song 2'),
