What does ECHO .> mean in batch file? - batch-file

I have a batch file with the following code within:
ECHO .> C:\file.txt
I read about ECHO and understand what it is used for, but what I do not know is what are the characters used for after the word echo (.>) and what is the use of the path of file after that.

It's used to truncate, or create if necessary, the file. echo . outputs a single line which is redirected to the file, effectively truncating it.
To obtain an absolutely empty file I often use cd . > filename. I don't know where I picked that one up but it's been around for a long time on UNIX systems.

> redirects the output of the command before.
echo .>c:\file.txtprints a dot to the file c:\file.txt, overwriting its contents (so it will contain a dot only afterwards)
I think, you got it wrong. Usually echo.>file.txt is used to create a empty file (or delete the contents, if the file exists). (Note the missing space)

Related

Batch File Calls VB Script & Passes Filename as String Only

I have a batch file that calls a VB Script file. This VB Script comes from MS Office Suite and is located in the Installed Folder. My file calls the VB Script and pipes it to a file using the > symbol. This works if your redirect is a string. I was wondering how to redirect to a file using a variable.
I'm only including a small fraction of the code showing how I want it to work.
This, as written, works. However I want my batch file to use a variable instead of the text in quotes. In fact, my batch file creates the path depending on where the batch file is located.
::Create file and display on screen
Echo Writing Information to File: "OfficeStatus.txt"
Call cscript ospp.vbs /dstatus > OfficeStatus.txt
Echo.
When written as shown below, it does not work:
::Create file and display on screen
Echo Writing Information to File: "OfficeStatus.txt"
Call cscript ospp.vbs /dstatus > %_sLogFile%
Echo.
I don't know if the issue is because of the redirect not able to handle a variable or not. An example of what might be in the variable:
_sLogFile=E:\UserName\Documents\Status\OfficeStatus.txt.
Any thoughts would be great.
The variable, by the way, correctly contains the path and filename... so that's not the issue.
it does not work means did not do what I expected and unfortunately does not tell us what it did do.
Did it crash the system? Create an error message (If so, what message)? Create an output file in an unexpected place??
Personally, I'd suspect what you have concealed as username. Without knowing precisely what that text is, we start guessing, which isn't a logical approach. It doesn't have to be the real username, substitute Fred Bloggs for the real name to mask it if necessary.
I believe that username may either be %username% to retrieve the name from the system, or a real literal. The problem with this is that such names often contain spaces, you'd need to "Enclose the full filename in quotes".
See - had you told us _sLogFile=E:\Fred Bloggs\Documents\Status\OfficeStatus.txt it would all have been a lot clearer - presuming that my guess as to the cause of the problem is correct.
Perhaps you should look for files named like E:\Fred which is where the expected output may have ended up.

Escape characters of a file path argument for a batch file

I was making a batch file to take dragged-and-dropped folders for program input. Everything was working fine until I passed a folder, which for the sake of this post, called foo&bar.
Checking what %1 contained inside the batch file looked like C:\path\to\foo or C:\path\to\foo\foo. If the file path were in quotes it would work, so the only working code that slightly takes this into effect is :
set arg1=%1
cd %arg1%*
set arg1="%CD%"
Which changes directory to the passed argument using wildcards. However this only works once for if there is another folder with un-escaped characters inside the parent folder, passing the child folder would result in the parent folders' value.
I tried the answer of this post, which suggests to output the argument using a remark and redirection statement during an #echo on sequence. However no progress occurred in rectifying the problem. Any suggestions?
To recap, I am looking for ways to pass folders with un-escaped characters as arguments to a batch file. The implementation should preferably be in a batch file, but answers using VBScript are welcome. However the starting program must be in batch as this is the only program of the 3 that accepts files as arguments.
To test this, create a batch file with following code:
#echo off
set "arg1=%~1"
echo "the passed path was %arg1%"
pause
Then create folders called foobar and foo&bar. Drag them onto the batch file to see their output. foo&bar will only return C:\path\to\foo.
OK, so the problem is that Explorer is passing this as the command line to cmd.exe:
C:\Windows\system32\cmd.exe /c ""C:\path\test.bat" C:\path\foo&bar"
The outermost quotes get stripped, and the command becomes
"C:\working\so46635563\test.bat" C:\path\foo&bar
which cmd.exe interprets similarly to
("C:\working\so46635563\test.bat" C:\path\foo) & bar
i.e., bar is considered to be a separate command, to be run after the batch file.
The best solution would be to drag-and-drop not directly onto the batch file but onto, say, a vbscript or a Powershell script or a plain old executable. That script could then run the batch file, either quoting the argument appropriately or putting the directory path into an environment variable rather than on the command line.
Alternatively, you can retrieve the original command string from %CMDCMDLINE% like this:
setlocal EnableDelayedExpansion
set "dirname=!CMDCMDLINE!"
set "dirname=%dirname:&=?%"
set "dirname=%dirname:" =*%"
set "dirname=%dirname:"=*%"
set "dirname=%dirname: =/%"
for /F "tokens=3 delims=*" %%i in ("%dirname%") do set dirname=%%i
set "dirname=%dirname:/= %"
set "dirname=%dirname:?=&%"
set dirname
pause
exit
Note the exit at the end; that is necessary so that cmd.exe doesn't try to run bar when it reaches the end of the script. Otherwise, if the part of the directory name after the & happens to be a valid command, it could cause trouble.
NB: I'm not sure how robust this script is.
I've tested it with the most obvious combinations, but YMMV. [It might be more sensible to use delayed expansion exclusively, I'm not sure. It doesn't seem to be necessary except in the first set command. Jeb's answer here might be a better choice if you're going this route.]
For the curious, the script works like this:
Load the original command line into dirname [necessary for the reason pointed out by jeb]
Replace all the & characters with ?
Replace all the quote marks with *
If a quote mark is followed by a space, suppress the space.
NB: it is necessary to suppress the space to deal with both the case where the path contains a space (in which case Explorer adds quote marks around it) and the case where it doesn't.
Replace all remaining spaces with /
NB: ? * and / are illegal in file names, so these replacements are safe.
At this point the string looks like this:
C:\Windows\system32\cmd.exe//c/**C:\path\test.bat**C:\path\foo?bar**
So we just need to pull out the third asterisk-delimited element, turn any forward slashes back into spaces and any question marks back into ampersands, and we're done. Phew!

How to other write file using gawk script?

I have written one code for remove duplicates from CSV file & now i want to save file with its original name. I dont want to save as with different name. Below is the batch script :
Code :
#echo off
C:\sw\awk\bin\gawk.exe "!x[$0]++" *.csv > "{print FILENAME, $0 > FILENAME ".csv"}" file*
My Objective is : I want to build dynamic batch script which will run on any CSV file. There should not be any type of dependency(file name).
Error is :
The filename, directory name or volume label syntax is incorrect.
Please help me with this.
Thanks.
This batch file is trying to redirect output from gawk into a file called {print FILENAME, $0 > FILENAME, which is not a valid filename.
At present, the gawk code produces a single output that omits all duplicate lines in all of the CSV files in the directory.
If you want to omit duplicate lines from each CSV file individually and write each file out individually, you will need a loop in the batch file to present each CSV file to the gawk script individually and output each modified file individually. You can do that as follows (presuming tmp.tmp is not an existing file in the folder):
for %%f in (*.csv) do (
gawk.exe "!x[$0]++" "%%f" >tmp.tmp
copy tmp.tmp "%%f"
)
del tmp.tmp
As a cautionary note, on DOS or Windows if you write through standard output to a file that you are reading, you can overwrite the file that you are reading before you've finished reading it. That is why the code above writes to a temporary file and then copies the temporary file to the original file.
There are a number of problems with your attempt. Firstly, you cannot write to the same file that you're reading from (at least, not while you're reading from it). Secondly, you're using the awk special variable FILENAME outside of the awk script, where it doesn't exist.
The following may work for a single file at a time. It reads the entire file in, using the line as the key of an associative array and using the line number as the value. Then in the END block, it prints the array out in order of the values, writing to the file it just read.
gawk "!($0 in a) {a[$0] = NR} END {PROCINFO[\"sorted_in\"]=\"#val_num_asc\"; for(x in a) print x >FILENAME}"

Compare output of "DOS" command to something

(by DOS I mean windows cmd.exe - I don't want to enforce powershell or similar on the end user)
I want to run a command line file that prints output to CON / the screen.
I want to capture that output and compare it to an expected output.
... in a .bat / .cmd file?
Specifically, the identify command of ImageMagick, and I want to run this over +- 300 files and compare the actual sizes to expected sizes.
example output:
$ identify rose.jpg
rose.jpg JPEG 640x480 sRGB 87kb 0.050u 0:01
If I understand the question correctly, you want to run the identify command on all the jpg files in a directory and capture the output of that command into a text file for later comparison. The comparison however is not part of the spec?
Something like the line below should do that job. Just run it from the folder the jpg files are located:
for /R %%X in (*.jpg) do identify %%X >> PicInfo.txt
This will capture the rose.jpg JPEG ... line for every .jpg file you have in the directory (and subdirectories thanks to '/R') that you run the command in and append it to the file PicInfo.txt.
You can call your identify program with a symbol that redirects console output to a file, which is the > character. Something like:
identify rose.jpg > myoutput.txt
Additionally, the >> will append output to what is already in the file. So using
identify rose.jpg >> myoutput.txt
...should create one file with all your output.
You can then use the DOS COMP command, which compares the contents of two files. The syntax is:
COMP [data1] [data2] [/D] [/A] [/L] [/N=number] [/C] [/OFF[LINE]]
Which you could also redirect to an output file using the > symbol.

How to create empty text file from a batch file?

Can somebody remember what was the command to create an empty file in MSDOS using BAT file?
copy NUL EmptyFile.txt
DOS has a few special files (devices, actually) that exist in every directory, NUL being the equivalent of UNIX's /dev/null: it's a magic file that's always empty and throws away anything you write to it. Here's a list of some others; CON is occasionally useful as well.
To avoid having any output at all, you can use
copy /y NUL EmptyFile.txt >NUL
/y prevents copy from asking a question you can't see when output goes to NUL.
echo. 2>EmptyFile.txt
This redirects output stream 2 (stderr) to a file. The command echo doesn't output anything to stderr, so the file becomes empty.
Plain echo would work too, but echo. is better because it doesn't print the useless and potentially confusing message ECHO is on.
type NUL > EmptyFile.txt
After reading the previous two posts, this blend of the two is what I came up with. It seems a little cleaner. There is no need to worry about redirecting the "1 file(s) copied." message to NUL, like the previous post does, and it looks nice next to the ECHO OutputLineFromLoop >> Emptyfile.txt that will usually follow in a batch file.
Techniques I gathered from other answers:
Makes a 0 byte file a very clear, backward-compatible way:
type nul >EmptyFile.txt
idea via: anonymous, Danny Backett, possibly others, myself inspired by JdeBP's work
A 0 byte file another way, it's backward-compatible-looking:
REM. >EmptyFile.txt
idea via: Johannes
A 0 byte file 3rd way backward-compatible-looking, too:
echo. 2>EmptyFile.txt
idea via: TheSmurf
A 0 byte file the systematic way probably available since Windows 2000:
fsutil file createnew EmptyFile.txt 0
idea via: Emm
A 0 bytes file overwriting readonly files
ATTRIB -R filename.ext>NUL
(CD.>filename.ext)2>NUL
idea via: copyitright
A single newline (2 bytes: 0x0D 0x0A in hex notation, alternatively written as \r\n):
echo.>AlmostEmptyFile.txt
Note: no space between echo, . and >.
idea via: How can you echo a newline in batch files?
edit It seems that any invalid command redirected to a file would create an empty file. heh, a feature!
compatibility: uknown
TheInvisibleFeature <nul >EmptyFile.txt
A 0 bytes file: invalid command/ with a random name (compatibility: uknown):
%RANDOM%-%TIME:~6,5% <nul >EmptyFile.txt
via: great source for random by Hung Huynh
edit 2 Andriy M points out the probably most amusing/provoking way to achieve this via invalid command
A 0 bytes file: invalid command/ the funky way (compatibility: unknown)
*>EmptyFile.txt
idea via: Andriy M
A 0 bytes file 4th-coming way:
break > file.txt
idea via: foxidrive thanks to comment of Double Gras!
REM. > empty.file
If there's a possibility that the to be written file already exists and is read only, use the following code:
ATTRIB -R filename.ext
CD .>filename.ext
If no file exists, simply do:
CD .>filename.ext
(updated/changed code according to DodgyCodeException's comment)
To supress any errors that may arise:
ATTRIB -R filename.ext>NUL
(CD .>filename.ext)2>NUL
One more to add to the books - short and sweet to type.
break>file.txt
break>"file with spaces in name.txt"
fsutil file createnew file.cmd 0
You can use a TYPE command instead of COPY. Try this:
TYPE File1.txt>File2.txt
Where File1.txt is empty.
There are infinite approaches.
Commands that output nothing:
break
cls
color
goto
pushd
popd
prompt
title
Weird Commands:
CD.
REM.
#echo off
cmd /c
START >FILE
The outdated print command produces a blank file:
print /d:EMPTY_TEXT_FILE nul
You can also use SET to create a null byte file as follows
set x=x > EmptyFile.txt
Or if you don't want to create an extra variable reassign an existing variable like
set PROMPT=%PROMPT% > EmptyFile.txt
or like this:
set "PROMPT=%PROMPT%" > EmptyFile.txt
The easiest way is:
echo. > Filename.txt
IMPORTANT:
If you don't set the encoding, many softwares can break. git is a very popular example.
Set-Content "your_ignore_file.txt" .gitignore -Encoding utf8 this is case-sensitive and forces utf8 encoding!

Resources