I've script that reads into variable content of files, but in some cases, files has new lines. Variable has loaded olny firest line. I use:
set /p varfile=file.txt
Is it possible to read contents of the file with ignored newlines? I cannot find solition wihtin batch commands.
Although this is probably not what you need, this is what you asked for. You can capture the entire contents of a file to a single variable (up to 8191 bytes, is it?) by using a for loop. Since for /f can read the contents of a file, you can finally eliminate that set /p statement you keep misusing.
#echo off
setlocal enabledelayedexpansion
rem // capture a line break to a variable
set BR=^
rem // Leave the two lines above blank.
for /f "usebackq delims=" %%I in ("file.txt") do (
if not defined contents (
rem // set contents variable to first line of file
set "contents=%%I"
) else (
rem // append line break + next line to variable
set "contents=!contents!!BR!%%I"
)
)
echo(!contents!
Now, what are you going to do with this variable now that it contains the entire contents of a text file?
Related
I am trying to loop through a folder of files and rename them based on the last characters of the file. These files do not have extensions. My goal is:
file ends with TXT eg ItemTXT, move it to the same location and rename as Item.txt
file does not end with TXT, move it to the same location and rename as Item.xxx
I think I on the right track, but for some reason the if/else returns the else consition every time I test
#echo off
setlocal EnableDelayedExpansion
set pat=C:\Users\king\latest30
echo %pat%
for %%g in (%pat%\*) do (
set fnamelast3="%%~nxg:~-3%"
echo filename: %%~nxg fnamelast3: %fnamelast3%
if "%fnamelast3%" neq "TXT" (
echo %pat%/%%~nxg.fil
) ELSE (
rem does send with TXT
echo %pat%/%fname%.txt
)
)
Variables are not behaving as expected
even though you are setting delayedexpansion, you are not using it.
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign " or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier.
You should find that %%g in (%pat%\*.) will select extensionless files.
set fnamelast3="%%~nxg:~-3%"
is invalid; you can't substring metavariables like %%g. You need to use
set "fname=%%~nxg"&set "fnamelast3=!fname:~-3!"&set "fnameexcept3=!fname:~0,-3!"
then use !fnamelast3! & !fnameexcept3! to rename your file - and you no longer need to detect txt since you will only be processing extensionless files which get their last three characters used as an extension
REM timestamped name of file
set PREFIX=LINE_
set SAVESTAMP=%PREFIX%%DATE:/=-%_%TIME::=-%
set SAVESTAMP=%SAVESTAMP: =%
set SAVESTAMP=%SAVESTAMP:,=.%.txt
echo %SAVESTAMP%
REM In H.txt, for each line grab the text after delimiter ':' and send it to file
for /f "tokens=2 delims=:" %%a in ('type D.txt^|find ":"') do (
set line=%%a
REM#1
echo %line% >> %SAVESTAMP%
)
REM#2
REM echo %line% >> %SAVESTAMP% ---This output one line
When I use REM#1 and comment the second echo outside the for loop, there is not file created.
But when I use REM#2 and don't use REM#1 echo a file with one line is created.
Most times the file will have multiples lines written to it.
So I want this working inside the for loop.
D.txt
line1:sample1
line2:sample2
line3:sample3
line4:sample4
Output should be :
Line_Date_TimeStamp.txt
sample1
sample2
sample3
sample4
Two problems:
First, there must be a separator (like a space) between rem and the text, otherwise an attempt to find and execute an executable named rem#1.(bat,exe etc.) is made.
Second, you need to search SO for delayed expansion as you are attempting to show the value of a variable (line) that is being modified within the for block.
I wanted to take list of files to delete from user as a argument. One line per argument.
How can store the list of files separated by new line in a variable.
I am using below command.
Set DeletionFiles=${p:DeleteFiles}"
for %%i in (%DeletionFiles%) do (
echo %%i
)
Then i wanted to iterated them on a loop.
${p:DeleteFiles} will get replaced by it's value from external app, which will contain list of files separated by new line.I can not change it.
#ECHO OFF
SETLOCAL
SET "deletionfiles="
:dloop
SET "deleteme="
SET /p "deleteme=Which file to delete ? "
IF DEFINED deleteme SET "deleteme=%deleteme:"=%"
IF DEFINED deleteme SET "deletionfiles=%deletionfiles%,"%deleteme%""&goto dloop
ECHO delete %deletionfiles:~1%
GOTO :EOF
There is no need to use a newline. Your for command (or a del command) will operate perfectly happily on a comma-(or space-)separated list.
Note that there are certain characters that batch uses for special purposes and batch string-processing may not process them in the expected manner. These characters include % ^ and &.
${p:DeleteFiles} will get replaced by it's value from external app,
which will contain list of files separated by new line.I can not
change it.
After the replacement the batch file looks like:
Set DeletionFiles=file1.jpg
file2.jpg
file3.jpg
"
This isn't a valid batch file anymore.
Furthermore it's a bad idea to modify the batch file itself, as this works only once.
You could place the ${p:DeleteFiles} into another file, like input.txt.
Your batch would look like
echo ${p:DeleteFiles} > input.txt
<external program for replacing the DeleteFiles> input.txt
for /F "tokens=*" %%A in (input.txt) do (
echo File: %%A
)
If I understand you correctly, your external program will generate a list of files. You then want to store this multi-line list to a variable. What do you want to do with the variable once you have it? I assume you want to delete the files, but your question isn't clear on that point, so I'll try to over-answer to cover it.
for /f "delims=" %%a in ('{command that generates your list}') do (
echo Doing stuff to %%a...
echo %%a>>listOfFilesToDelete.txt
set var=%%a
if "%var:~0,7%"="DoNotDelete" copy "%%a" \someArchiveFolder\
del "%%a"
)
This will read each line in your generated list as variable %%a. It will then do whatever command(s) you specify. This way, you can run a command on each of the files in the list. In the above code it's
Printing each line to the console embedded in some text
Outputting it to a file
Checking the first 7 characters of the line against a specified string and then copying it to a folder if it matches
And then deleting it
If you still need to reference each line from your generated list, you can even setup an array-like structure. (See Create list or arrays in Windows Batch)
setlocal EnableDelayedExpansion
:: Capture lines in an 'array'
set /a i=0
for /f "delims=" %%a in ('dir /b') do (
set /a i+=1
set var!i!=%%a
)
:: Loop through the 'array'
for /L %%a in (1,1,%i%) do (
echo Do more stuff with !var%%a!
)
Just like above, this will read each line in your generated list as variable %%a. It will then set a variable var!i! equal to the value of the current line. You can then reference each line as var1, var2, and so on, or, as the second section shows, you can loop through them all using for /L. You'll need to get a grasp on working with delayed expansion variables, though.
I need to echo a text file with multiple lines.
Here's what I've done, but this only echo's the first line.
set /p errorlog=<errorlog.txt
echo %errorlog%
pause
If you want to include the entire file, and don't really need the environment variable, why not type the file?
type errorlog.txt
Environment variables are not intended to hold the entire contents of the file, and cannot store newlines as values. The value will terminate at the first newline.
If you want it to be stored as a variable at one point, try:
for /f "tokens=* delims=" %%G in (errorlog.txt) do (
echo %%G
)
Note that this method can allow you to only echo part of a file if you include a count function, but is slower the longer errorlog.txt is.
in a batch I have
echo VirtualDub.video.AddComment^(0x0000000C,"","%tc%"^)^;>>v:\automazioneclip\virtualdubmod\temp\%%~na.vcf
but now in place of %tc% I would like insert the contents of a text file, all content of a text file
How I have to modify it? thanks
Use SET /P to print out the first portion of the line without a newline. Then use TYPE to print out the contents. Then finish up with a normal ECHO.
<nul (
set /p ^"=VirtualDub.video.AddComment^(0x0000000C,"",""
type file.txt
(echo ^"^);)
) >>"v:\automazioneclip\virtualdubmod\temp\%%~na.vcf"
Note that the closing quote after the file contents will appear on the next line if the file ends with a newline. Obviously the value will be spread across multiple lines if the file contains multiple lines. Multiple lines may or may not be a problem depending on the language of the code you are writing.
Related question: How do you loop through each line in a text file using a windows batch file?
So possibly something like:
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
where "process" is your line above.
for /F "tokens=*" %%A in (myfile.txt) do echo VirtualDub.video.AddComment^(0x0000000C,"","%%A"^)^;>>v:\automazioneclip\virtualdubmod\temp\%%~na.vcf