Jump to content

Prepend or "interpend" text to a text file via batch script


Recommended Posts

I can add text to a text file via batch with:

echo this is a new line>>filename.txt

What I want to do is put the new line at the beginning or somewhere in between. The "somewhere in between" is a static blank line so it would appear at the same place in every file I want to change. Any thoughts?

Straytoasters

Link to comment
Share on other sites


For 'interpend', although I'd generally suggest SED or G(nu)AWK for the task it can also be done in 'Pure' NT Command Script.

The method would greatly depend upon the content of both the 'text file' and 'text string'.

If you provide details I may provide a reasonable solution.

Link to comment
Share on other sites

Based on the information provided, the following may get you started:

@echo off

set offset=30
set filename=test.txt
set tempfile=temp.tmp
set linecount=0

::: Delete files if they exist
if exist %filename% del %filename%
if exist %tempfile% del %tempfile%

:: Populate file with dummy data for testing
for /l %%n in (1,1,35) do echo %%n>>%filename%

:: Loop through file to find line offset
setlocal enabledelayedexpansion
for /f %%# in (%filename%) do (
set /a linecount=!linecount!+1
if !linecount! EQU %offset% (
echo %%# Offset reached!>>%tempfile%
) else (
echo %%#>>%tempfile%
)
)
endlocal

The above simply allows you to change a line given the line number specified by the offset variable. A new file is created with the changes made. Additional changes could be made to check for a specific string at the offset line. Also, there is currently no error checking. If a file does not contain a given line offset, what should be done?

Hope that helps!

Link to comment
Share on other sites

Although this is slightly off topic, in order for you to understand what problems can arise from a lack of full information for the content here is an example text file:

existing.txt

I am the first line of this document.
I once stated, "I am the second line".
I demand to stay put! I don't wish to move!

Do you wish to stop & start notepad, just start it, or neither?

My email, <something@somedomain.ext>, is not working!

Note

Line 5 includes a trailing space after the question mark and line 6 contains a single space, both must be retained in the output file,
NewFile.ext
as must the blank line currently at line 4.

I would be interested to see a reasonably concise Windows NT Command Script using no third party programs which will add the text Text string added! into the file at line 3

I have started the script, anyone up for the challenge?

AddItIn.cmd

@Echo off&Setlocal
:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=3"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext"
Type Nul>%NF%

Link to comment
Share on other sites

Yzöwl here is my entry and it more of a cheat, sorry but Windows NT Command Script is not my best.

Save as a StringManipulation.vbs

Option Explicit
Const ForReading = 1
Const ForWriting = 2
Dim Fso :Set Fso = CreateObject("Scripting.FileSystemObject")
Dim C1, TFile1, TFile2, Ts, Txt1, Txt2
TFile1 = "existing.txt"
TFile2 = "NewFile.ext"
'/-> Check For File Exists
If Fso.FileExists(TFile1) Then
ProcessFile()
Else
MsgBox "Can not find " & TFile1, 4128, "Missing File"
End If
'/-> Process The Text File If Exists
Function ProcessFile()
Set Ts = Fso.OpenTextFile(TFile1, ForReading)
Do Until Ts.AtEndOfStream
Txt1 = Ts.ReadLine
C1 = C1 + 1
If C1 = 3 Then Txt2 = Txt2 & "Text string added!" & vbCrLf
Txt2 = Txt2 & Txt1 & vbCrLf
Loop
Set Ts = Fso.OpenTextFile(TFile2,ForWriting,True)
Ts.WriteLine Txt2
Ts.Close
CreateObject("Wscript.Shell").Run ("Notepad.exe " & Chr(34) & TFile2 & Chr(34)),1,True
'/-> UnComment If You Want To Delete The File
' Fso.DeleteFile(TFile2),True
End Function

Edited by Yzöwl
Link to comment
Share on other sites

Ok, after a few days of scratching my head and trying many elaborate combinations, I have come up with the following:

@echo off

set linecount=0
:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=3"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext

echo %TS%>insert.txt

if exist top.txt del top.txt
for /f "tokens=*" %%l in (%EF%) do (
call :inc linecount
call :print %%l
)

call :dec LN

more +%LN% %EF%>last.txt

copy /b top.txt+insert.txt+last.txt %NF%>nul
goto end

:print
if %linecount% LSS %LN% echo %*>>top.txt
goto :eof

:dec
set /a %1=%1-1
goto :eof

:inc
set /a %1=%1+1
goto :eof

:end

This is using no external utilities. Works under Windows XP.

Thoughts?

Tidied version:

@Echo off&Setlocal
:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=3"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext
::Type Nul>%NF%
Set LC=0
Echo/%TS%>_#$_2
For /f "delims=" %%# In (%EF%) Do (Set/a LC +=1&Call :PR_ %%#)
Set/a LN -=1
More +%LN% %EF%>_#$_3
Copy/b _#$_1+_#$_2+_#$_3 %NF%>Nul&&Del _#$_*
Goto :Eof
:PR_
If %LC% Lss %LN% Echo/%*>>_#$_1

Link to comment
Share on other sites

Superb GSM, I'm happy to leave your vbscript solution here to help show how much quicker it'll work than a batch only solution. Because it edits a stream as SED would but is built-in it deserves its place in this thread

I just thought I'd clarify for anyone interested that the expected output should be:

@Echo off&Setlocal
:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=3"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext"
::Type Nul>%NF%
Set/a PL=LN-1
Sed -n 1,%PL%p %EF%>%NF%
Echo:%TS%>>%NF%
Sed -n %LN%,$p %EF%>>%NF%

GAWK

@Echo off&Setlocal
:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=3"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext
::Type Nul>%NF%
Set/a PL=LN-1
Gawk "{print;if(NR==%PL%)print"""%TS%"""}" %EF%>%NF%

Congratulations Scr1ptW1zard, we have a working entry according to the original specification.

I have nothing but admiration for you for giving this a shot, was intrigued by your approach and love your use of the copy switch! I may be completely wrong but I have no recollection of seeing a script attempt this 'simple' task anywhere on the net and didn't expect anyone to take up the 'pointless' challenge. I'm however a little bit disappointed with one particular aspect; It seems as if it produces the output quicker than mine, the difference isn't much but I'm sure that if I was adding a line to a large file mine would be a lot slower.

Now for the kicker, to show how different content can really affect your work, change the insert line number to 13 and change the existing.txt to:

	Column 1	|	Column 2

A variable is enclosed in percent signs: %var1%

10% of 42 = 5% of 21
My email, <something@somedomain.ext>, is not working!

Do you wish to stop & start notepad, just start it, or neither?

I demand to stay put! I don't wish to move!
I stated, "I am in the middle of something".


I stated, "I am in the middle of something".
I demand to stay put! I don't wish to move!

Do you wish to stop & start notepad, just start it, or neither?

My email, <something@somedomain.ext>, is not working!
10% of 42 = 5% of 21

A variable is enclosed in percent signs: %var1%

Column 1 | Column 2

Lines

Notes
This file is mirrored, first and last lines say
<
TAB
>Column 1<
TAB
>|<
TAB
>Column 2

Lines 7 and 18 contain a single space

Lines 8 and 17 end with a trailing space

Now start pulling your hair out!

BTW, my solution adds just a single line to my 'starter' script, which I split, for beautifying reasons, into three

P.S I'm going to edit/append posts etc. in order not to completely ruin the original intent of the topic and try to keep only the better attempts here!

Link to comment
Share on other sites

Congratulations Scr1ptW1zard, we have a working entry according to the original specification.

I have nothing but admiration for you for giving this a shot, was intrigued by your approach and love your use of the copy switch! I may be completely wrong but I have no recollection of seeing a script attempt this 'simple' task anywhere on the net and didn't expect anyone to take up the 'pointless' challenge. I'm however a little bit disappointed with one particular aspect; It seems as if it produces the output quicker than mine, the difference isn't much but I'm sure that if I was adding a line to a large file mine would be a lot slower.

Wow! Thank you for the compliment Yzöwl! :rolleyes:

This was one of those challenges that I just could not stop working on. So many times I was getting close but missing one special character. I ended up scraping everything and starting from scratch today with a completely different thought process. Methodically stepping through what needed to be done, made me see a straight-forward solution.

Thank you very much for your comments. I am glad to contribute to this fine community.

<Edit> : Updated solution for changed parameters

I think this should handle all the requirements:


@echo off

:: Existing Filename [to add text to]
Set "EF=existing.txt"
:: Line Number [to insert string]
Set "LN=13"
:: Text String [to add]
Set "TS=Text string added!"
:: New Filename [as updated document]
Set "NF=NewFile.ext"

if exist %NF% del %NF%
call :_dec LN
for /L %%# in (1,1,%LN%) do (
call :_doit %%#
)
echo %TS%>>%NF%
more +%LN% %EF%>>%NF%
goto _end

:_dec
set /a %1 -=1
goto :eof

:_doit
findstr /N /R "." %EF%|findstr /B /C:"%1:">nul
if errorlevel 1 (
echo.>>%NF%
) else (
for /f "tokens=1,* delims=: " %%a in ('findstr /N /R "." %EF%^|findstr /B /C:"%1:"') do (
if [%%b] EQU [] (
echo. >>%NF%
) else (
echo %%b>>%NF%
)
)
)
goto :eof

:_end

A bit slower as the line number for the insertion is increased. I tested inserting the line at each line of the file as well as lines that do not exist. When entering a line greater than the number of lines in the file, additional lines are added to reach the desired line.

</Edit>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...