Echoing to a file results in spaces in Batch - windows

Using a batch file (.bat), I'm making a script that requires dynamic paths so that it can work on multiple computers. My problem is when I echo something to a file, it adds a line and an a return carriage.
Say I have a text file named foo.txt in the directory of the batch file, and its contents are completely empty.
In the batch file, I run:
echo test > foo.txt
The contents of foo.txt will be:
L1: foo
L2:
There would be a space after foo in the first line and a second empty line. Now, this would be completely okay and I would entirely ignore it, but filename paths do not ignore it.
importing text from foo.txt like so:
set /p foo=< foo.txt
...and then:
set /p name=< C:\A.D.V.E.N.T.U.R.E.\test\%foo%\test2.txt
...would be interpreted as:
set /p name=< C:\A.D.V.E.N.T.U.R.E.\test\foo \test2.txt
Including an unwanted space. Is there anyway to make it so you can write text to a file without a space, or a command one could use to delete the carriage return and the space?

You can also use parentheses to make sure unwanted space is not included in the output:
(echo test) >foo.txt

The data should be test, not foo
Clasically, try
>foo.txt echo test
but make sure that there are no trailing spaces after test.
(to APPEND to foo.txt use >> in place of >)

above given answers works.
But, the actual reason I found for it was the space before >
So, instead of
echo test > foo.txt
it must be
echo test> foo.txt
NOTE. Don't put any space between test and >. This, results in a trailing space.

Related

CMD/BATCH BAT SCRIPT How to add digit to file without space

i want to make a start.config file by using bat script.
I want to add to my config file that parameter:
StartAgents=9
WITHOUT space at the end of line.
Unfortunately command:
echo StartAgents=9>>C:\start.config
not working, I think that there is "collision" with two characters: "9>"
Command:
echo StartAgents=9 >>C:\start.config
is working, but this is adding space at the end of line in my config file - i dont want that.
Any ideas how to do that?
I want to add line StartAgents=9 without space af the end of line.
want:
StartAgents=9
dont want:
StartAgents=9
You have to escape the number, so that it isn't interpreted by CMD.EXE as a file descriptor number.
Then you can add the >> redirection directly after the number to not insert a trailing space.
Example:
echo StartAgent=^9>>test.txt
Related Information:
Omitting trailing space
File Descriptor Usage

Word Sorting in Batch

Right let me rewrite this try to make it more clear.
Picture added to make this even clearer:
I have two files
File 1, contains words.
file 2, contains commands.
I need to put words from FILE 1
into FILE 2
I cannot copy-paste them one by one, because there is a LOT of words in FILE 1
File 1 is listed in alphabetical order (by first letter)
File 2 the command does not change
The issue is getting words from file 1 into file 2
but they have to be moved into quotes " " in file 2
so a script that could for example..
Take apple from file 1 and move it between quotes admin.executemotecommand "apple"inside file 2 as it goes down the list keeping the words in order as they move them across.
This could perhaps be done the same way around in which, the script writes the command in front of the words in file 1 as it goes down file 1's list
Is this even possible? I've never seen this done anywhere else and completely clueless if batch is even the right language for it.
The question is a little confusing, but based on your responses in the comments my understanding is that you don't necessarily need the script to edit a preexisting file 2, because you're repeating the same command(s) for each word, so the script can just create a new file based on the words in file 1.
You can do it at the prompt like this:
FOR /F %a IN (words.txt) DO ECHO admin.executeremotecommand "%a" >> commands.txt
The original version of the question indicated that you want more than one command for each word. I take it you changed that in order to simplify that question, and figured you'd just run the script once for each command? However, it's quite simple to have it produce more than one command for each word:
FOR /F %a IN (words.txt) DO (ECHO first.command "%a" & ECHO second.command "%a") >> commands.txt
In a batch file, you'd do it this way:
#ECHO OFF
FOR /F %%a IN (words.txt) DO (
ECHO first.command "%%a"
ECHO second.command "%%a"
) >> commands.txt
BTW, in the code in some of your comments, you surrounded the variable with %'s (%A%). That's incorrect; it would evaluate to the value of %A followed by a literal %. Surrounding with %'s is used only for environment variables. (Note that the %'s around environment variables do not get doubled in a batch file. For example, to get the current date, use ECHO %date% both at the prompt and in a batch file.)

Unexpected command line behavior using commas in Windows/DOS batch file

Today, I wanted to test if filenames can contain commas and stumbled upon something else while opening cmd and trying these three tests:
echo a,b>a
This works as supposed (writes a,b to the file named a)
echo a>a,b
Does just the same! What happens here gets a bit clearer with the third test:
echo a>file,b this is a test
This will create a file named file containing a,b this is a test.
Now, three questions arise for me:
What is the explanation for this? If someone asked me, I would've guessed the comma separates commands or filenames, e.g. I would've expected the second test to create two files named a and b.
Is this behaviour documented somewhere?
Is it a cmd specific Windows extension or has it been like this since good old DOS times?
It's expected behaviour as ,;=<space><tab> are delimiters for parameters.
If you put the code into a batch file without echo OFF you will see
test.bat
echo a,b>a
echo a>a,b
echo a>file,b this is a test
Output
C:\temp>test.bat
C:\temp>echo a,b 1>a
C:\temp>echo a,b 1>a
C:\temp>echo a,b this is a test 1>file
After a redirection, only the next token is relevant, the rest is part of the normal line content.
It's unimportant where the redirection occurs in a line.
But there is the rule that when more than one redirection exists for the same stream, the last one will win.
> file.txt echo hello> nul world > con
This will result in hello world at the console.
Btw. There is still an obscure behaviour with redirection and lines extended by carets (multilines).
echo one two three^
four
Result: one two three four
But
echo one two >con three^
four
Result: one two four
The comma is a standard delimiter in batch as well as ; <space> = <tab> and everything after the comma is taken as another parameter to echo and only one parameter is taken for the redirection. You can try to enclose a,b in quotes and this should change the behaviour of the output and produce a,b file. You can also escape the delimiters with ^ - echo a>a^,b
You can try also echo a>a=b - it will be the same.

why using echo is replacing old text in .txt file?

I want to use echo to add data into a text file progressively. I wrote a small batch code as follows:
#echo off
echo >text.txt
set DllCopier_d=./DllCopier
echo %DATE:~04%>text.txt
echo %TIME:~0,5%>text.txt
echo %~dp0%>text.txt
When I look at text.txt at the end, i found only one line:
C:\omsstest_automation\win32\
Which is result of last line.
Why is the "echo" resulting into replacing previous contents of text.txt?
> means create a new file with these contents (replace the old if it exists), >> means append or create a new file if none already exists.
So to spell out the answer to your question, replace subsequent usages of > after the very first one with >>.

Windows batch script to copy and modify files containing redirect characters

We are trying to convert a bash shell script into a Windows batch script. We ship these scripts with our software product, and we cannot assume that the customer will have, or will be able to download, sed/awk/cygwin or any other non-standard tools. Therefore, the script must work with whatever tools come out-of-the-box with Windows. The minimum target platform is Windows XP SP2. This script is called from another batch script.
One part of the script needs to search through a file for a particular string and modify that string. In bash, this is easy. The approach we are taking in the Windows batch script is to walk through the file, line by line. If a line does not contain the target string, we echo it to a temp file as-is. If a line contains the target string, we echo a hardcoded string to the temp file.
The problem is that some lines of the input file contain the less-than and greater-than signs. If we put quotation marks around the lines, they are written intact to the temp file, but quoted.
"-- this is a comment in the output .sql file"
"SELECT foo FROM bar WHERE something < 10;"
"--<SpecialInternalTagComment>"
If we unquote them using %~1, then CMD.EXE attempts to treat the < and > as redirection symbols, and produces errors when the script encounters one of those lines, because the resulting command would be something like this:
echo --<SpecialInternalTagComment> >> temp.file
Here's what we have right now. It produces the file contents with every line enclosed in quotation marks.
:clean_install
echo New installation >> %INSTALL_LOG%
echo > %INSTALL_FOLDER%"\sql\oracle\table_maintenance_tmp.sql
for /f "usebackq tokens=* delims=" %%A in (table_maintenance.sql) do (
call :replace_width_and_write_line "%%A"
)
goto done
:replace_width_and_write_line
echo %1 | find "&&TARGET_STRING" > NUL
if %ERRORLEVEL% == 0 (
echo TABLE_PARTITION_WIDTH CONSTANT NUMBER := 7 ; >> %INSTALL_FOLDER%"\sql\oracle\table_maintenance_tmp.sql
goto :eof
)
echo %1 >> %INSTALL_FOLDER%"\sql\oracle\table_maintenance_tmp.sql
goto :eof
The question is, how can we echo the contents of a string to a file, unquoted, if the string contains redirect symbols? If that can't be done, then is there another way to accomplish our original goal, which is to take as input a file that may or may not contain a certain target string, and produce as output a file that is identical to the original file except that if that target string existed, it is replaced by a new string?
I've searched here on stackoverflow, and the two most useful questions are these:
* How do you strip quotes out of an ECHO’ed string in a Windows batch file?
* Dealing with quotes in Windows batch scripts
Note: Please don't suggest Cygwin, sed, awk, Perl, Python, Ruby, unx, or any other technology that does not ship with Windows XP out of the box. Those answers will be voted down.
Thanks,
shoover
I'd suggest using VBScript here to process the file. It's included by default as well and string handling is much less error-prone.
There is a possibility though, to escape the special characters before printing the line. It's tedious and slow, though.
First you need to have your line in an environment variable. Use quotes to avoid any special characters from messing everything up:
set "tmp=%~1"
Careful to put the quotes around the complete argument, not only the part after the =, since otherwise you'll end up with the quotes in the variable as well.
Then you can start escaping the special characters, one by one:
set "tmp=%tmp:<=^<%"
set "tmp=%tmp:>=^>%"
set "tmp=%tmp:&=^&%"
set "tmp=%tmp:|=^|%"
etc.
This should work, but manipulating environment variables is pretty slow, so in large files this won't be fun.
Following a short transcript of my playing around with those replacements. Embedded quotes in uneven numbers cause this to fail, though, so careful:
> set "a=foo <bar> baz"
> set a
a=foo <bar> baz
> echo %a%
The system cannot find the file specified.
> set "a=%a:<=^<%"
> set a
a=foo ^<bar> baz
> set "a=%a:>=^>%"
> set a
a=foo ^<bar^> baz
> echo %a%
foo <bar> baz
In general, I'd suggest using VBScript, though, as a readily-available alternative to batch files and much more powerful, or at least, less surprising in dealing with such things.
You can use edlin.
From its Wikipedia article:
"Its persistence can probably be
explained by the fact that it can be
invoked to automatically perform small
modifications on text files, by piping
a script of commands to it through
standard input."
Note however that it is not available on 64 bit versions of
Windows and line length is limited to 253 characters.
cscript is a standard component installed for Windows.
http://en.wikipedia.org/wiki/Windows_Script_Host
Below is a script that would clean out lines of text that would match on a regular expression. The script could be tweaked to add command line parameters for the search rgx and replacement text.
/*
One part of the script needs to search through a file for a particular string and modify that string.
In bash, this is easy. The approach we are taking in the Windows batch script is to walk through the
file, line by line. If a line does not contain the target string, we echo it to a temp file as-is.
If a line contains the target string, we echo a hardcoded string to the temp file.
*/
/**
* Usage: type <in.file> | cscript //Nologo test.js > <out.file>
*/
function main() {
var rgxScrubMatch = /<SpecialInternalTagComment>/;
var replacement = "safe text";
scrubLines(rgxScrubMatch, replacement, WScript.StdIn, WScript.StdOut);
}
main();
/**
* Will echo back line
*
* #param rgxScrubMatch uses replacement on match
* #param replacement string to replace entire line that matches
* #param input input stream
* #param output output stream
* #return undefined
*/
function scrubLines(rgxScrubMatch, replacement, input, output) {
while(!input.AtEndOfStream) {
var line = input.ReadLine();
if(rgxScrubMatch.test(line)) {
output.Write(replacement + "\r\n");
} else {
output.Write(line + "\r\n");
}
}
}

Resources