Getting Started With Windows Batch Scripting
Getting Started With Windows Batch Scripting
Windows batch scripting is incredibly accessible – it works on just about any modern Windows machine. You can
create and modify batch scripts on just about any modern Windows machine. The tools come out of the box: the
Windows command prompt and a text editor like Notepad.exe. It’s definitely far from the best shell scripting langauge,
but, it gets the job done. It’s my “duct tape” for Windows.
Windows gurus launch the command prompt using the keyboard shortcut Windows Logo Key+R (i.e., “Run”) >
Type cmd.exe then Enter. This is way faster than navigating the Windows Start Menu to find the Command
Prompt.
The universal text editor for batch files is Notepad (Windows Logo Key + R > Type notepad then Enter). Since
batch files are just ASCII text, you can probably use just about any text editor or word processor. Very few editors do
anything special for Batch files like syntax highlighting or keyword support, so notepad is good enough fine and will
I would stick with Notepad for viewing the contents of a batch file. In Windows Explorer (aka, “My Computer”), you
should be able to view a batch file in Notepad by right clicking the file and seleting Edit from the context menu. If you
need to view the contents within a command prompt window itself, you can use a DOS command like TYPE
Assuming you are using Windows XP or newer, I recommend saving your batch files with the file extension .cmd.
Some seriously outdated Windows versions used .bat, though I recommend sticking with the more
modern .cmdto avoid some rare side effects with .bat files.
With the .cmd file extension, you can use just about filename you like. I recommend avoiding spaces in filenames, as
spaces only create headaches in shell scripting. Pascal casing your filenames is an easy way to avoid spaces
(e.g., HelloWorld.cmd instead of Hello World.cmd). You can also use punctuation characters like . or -
Another thing with names to consider is avoiding names that use the same name of any built-in commands, system
binaries, or popular programs. For example, I would avoid naming a script ping.cmd since there is a widely used
system binary named ping.exe. Things might get very confusing if you try to run ping and inadvertently
call ping.cmd when you really wanted ping.cmd. (Stay tuned for how this could happen.) I might called the
script RemoteHeartbeat.cmd or something similar to add some context to the script’s name and also avoid any
naming collisions with any other executable files. Of course, there could be a very unique circumstance in which you
want to modify the default behavior of ping in which this naming suggestion would not apply.
Notepad by default tries to save all files as plain jane text files. To get Notepad to save a file with a .cmd extension, you
will need to change the “Save as type” to “All Files (.)”. See the screenshot below for an example of saving a script
SIDEBAR: I’ve used a shortcut in this screenshot that you will learn more about later. I’ve saved the file to my “user profile
folder” by naming the file %USERPROFILE%\HelloWorld.cmd . The %USERPROFILE% keyword is the Windows
environmental variable for the full path to your user profile folder. On newer Windows systems, your user profile folder will
typically be C:\Users\<your username> . This shortcut saves a little bit of time because a new command prompt will
generally default the “working directory” to your user profile folder. This lets you run HelloWorld.cmd in a new command
prompt without changing directories beforehand or needing to specify the path to the script.
The easy way to run your batch file in Windows is to just double click the batch file in Windows Explorer (aka “My
Computer”). Unfortunately, the command prompt will not give you much of a chance to see the output and any errors.
The command prompt window for the script will disappear as soon as the script exits. (We will learn how to handle
think the easiest foolproof way to run your script is to drag and drop the script into a command prompt window. The
command prompt will enter the full path to your script on the command line, and will quote any paths containing
spaces.
You can recall previous commands using the up arrow and down arrow keys to navigate the command line history.
I usually run the script as %COMPSPEC% /C /D "C:\Users\User\SomeScriptPath.cmd" Arg1 Arg2 Arg3 This
runs your script in a new command prompt child process. The /C option instructs the child process to quit when your script quits.
The /D disables any auto-run scripts (this is optional, but, I use auto-run scripts). The reason I do this is to keep the command
prompt window from automatically closing should my script, or a called script, call the EXITcommand. The EXIT command
automatically closes the command prompt window unless the EXIT is called from a child command prompt process. This is
Comments
The official way to add a comment to a batch file is with the REM (Remark) keyword:
The power user method is to use ::, which is a hack to uses the the label operator : twice, which is almost always
ignored.
Most power authors find the :: to be less distracting than REM. Be warned though there are a few places where ::will
cause errors.
For example, a FOR loop will error out with :: style comments. Simply fall back to using REM if you think you have a
The first non-comment line of a batch file is usually a command to turn off printing (ECHO’ing) of each batch file line.
@ECHO OFF
The @ is a special operator to suppress printing of the command line. Once we set ECHO’ing to off, we won’t need
ECHO ON
Upon exit of your script, the command prompt will automatically restore ECHO to it’s previous state.
Batch files invole a lot of trial and error coding. Sadly, I don’t know of any true debugger for Windows batch scripts.
Worse yet, I don’t know of a way to put the command processor into a verbose state to help troubleshoot the script
(this is the common technique for Unix/Linux scripts.) Printing custom ad-hoc debugging messages is about your only
option using the ECHO command. Advanced script writers can do some trickery to selectively print debugging
messages, though, I prefer to remove the debugging/instrumentation code once my script is functioning as desired.
Variable Declaration
DOS does not require declaration of variables. The value of undeclared/uninitialized variables is an empty string,
or "". Most people like this, as it reduces the amount of code to write. Personally, I’d like the option to require a
variable is declared before it’s used, as this catches silly bugs like typos in variable names.
Variable Assignment
SET foo=bar
NOTE: Do not use whitespace between the name and value; SET foo = bar will not work but SET foo=bar will
work.
The /A switch supports arthimetic operations during assigments. This is a useful tool if you need to validated that user
SET /A four=2+2
4
A common convention is to use lowercase names for your script’s variables. System-wide variables, known as
environmental variables, use uppercase names. These environmental describe where to find certain things in your
system, such as %TEMP% which is path for temporary files. DOS is case insensitive, so this convention isn’t enforced
but it’s a good idea to make your script’s easier to read and troubleshoot.
WARNING: SET will always overwrite (clobber) any existing variables. It’s a good idea to verify you aren’t overwriting
a system-wide variable when writing a script. A quick ECHO %foo% will confirm that the variable foo isn’t an existing
variable. For example, it might be tempting to name a variable “temp”, but, that would change the meaning of the
widely used “%TEMP%” environmental varible. DOS includes some “dynamic” environmental variables that behave
more like commands. These dynamic varibles include %DATE%, %RANDOM%, and %CD%. It would be a bad idea to
In most situations you can read the value of a variable by prefixing and postfixing the variable name with
the %operator. The example below prints the current value of the variable foo to the console output.
There are some special situations in which variables do not use this % syntax. We’ll discuss these special cases later in
this series.
NOTE: Calling SET will list all regular (static) variables for the current session. This listing excludes the dynamic
environmental variables like %DATE% or %CD%. You can list these dynamic variables by viewing the end of the help text
By default, variables are global to your entire command prompt session. Call the SETLOCAL command to make
variables local to the scope of your script. After calling SETLOCAL, any variable assignments revert upon
calling ENDLOCAL, calling EXIT, or when execution reaches the end of file (EOF) in your script.
This example demonstrates changing an existing variable named foo within a script named HelloWorld.cmd. The
A real life example might be a script that modifies the system-wide %PATH% environmental variable, which is the list of
command.
Special Variables
There are a few special situations where variables work a bit differently. The arguments passed on the command line
to your script are also variables, but, don’t use the %var% syntax. Rather, you read each argument using a single %with
a digit 0-9, representing the ordinal position of the argument. You’ll see this same style used later with a hack to create
There is also a variable syntax using !, like !var!. This is a special type of situation called delayed expansion. You’ll
learn more about delayed expansion in when we discuss conditionals (if/then) and looping.
You can read the command line arguments passed to your script using a special syntax. The syntax is a
single %character followed by the ordinal position of the argument from 0 – 9. The zero ordinal argument is the name
of the batch file itself. So the variable %0 in our script HelloWorld.cmd will be “HelloWorld.cmd”.
The command line argument variables are * %0: the name of the script/program as called on the command line;
always a non-empty value * %1: the first command line argument; empty if no arguments were provided * %2: the
second command line argument; empty if a second argument wasn’t provided * …: * %9: the ninth command line
argument
NOTE: DOS does support more than 9 command line arguments, however, you cannot directly read the 10th
argument of higher. This is because the special variable syntax doesn’t recognize %10 or higher. In fact, the shell
reads %10 as postfix the %0 command line argument with the string “0”. Use the SHIFT command to pop the first
argument from the list of arguments, which “shifts” all arguments one place to the left. For example, the the second
argument shifts from position %2 to %1, which then exposes the 10th argument as %9. You will learn how to process a
Command Line Arguments also support some really useful optional syntax to run quasi-macros on command line
arguments that are file paths. These macros are called variable substitution support and can resolve the path,
timestamp, or size of file that is a command line argument. The documentation for this super useful feature is a bit
hard to find – run ‘FOR /?’ and page to the end of the output.
%~1 removes quotes from the first command line argument, which is super useful when working with arguments to file paths.
You will need to quote any file paths, but, quoting a file path twice will cause a file not found error.
SET myvar=%~1
%~f1 is the full path to the folder of the first command line argument
%~fs1 is the same as above but the extra s option yields the DOS 8.3 short name path to the first command line argument
(e.g., C:\PROGRA~1 is usually the 8.3 short name variant of C:\Program Files). This can be helpful when using third
%~dp1 is the full path to the parent folder of the first command line argument. I use this trick in nearly every batch file I write to
determine where the script file itself lives. The syntax SET parent=%~dp0 will put the path of the folder for the script file in
name of the script at runtime. If I need to print messages to the user, I like to prefix the message with the script’s name, like ECHO
%~n0: some message instead of ECHO some message . The prefixing helps the end user by knowing the output is from
the script and not another program being called by the script. It may sound silly until you spend hours trying to track down an
obtuse error message generated by a script. This is a nice piece of polish I picked up from the Unix/Linux world.
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
The SETLOCAL command ensures that I don’t clobber any existing variables after my script exits.
The ENABLEEXTENSIONS argument turns on a very helpful feature called command processor extensions. Trust me,
you want command processor extensions. I also store the name of the script (without the file extension) in a variable
named %me%; I use this variable as the prefix to any printed messages (e.g. ECHO %me%: some message). I also
store the parent path to the script in a variable named %parent%. I use this variable to make fully qualified filepaths
By convention, command line execution should return zero when execution succeeds and non-zero when execution
fails. Warning messages typically don’t effect the return code. What matters is did the script work or not?
The environmental variable %ERRORLEVEL% contains the return code of the last executed program or script. A very
helpful feature is the built-in DOS commands like ECHO, IF, and SET will preserve the existing value
of %ERRORLEVEL%.
The conventional technique to check for a non-zero return code using the NEQ (Not-Equal-To) operator of
the IFcommand:
IF %ERRORLEVEL% NEQ 0 (
REM do something here to address the error
)
IF ERRORLEVEL 1 (
The ERRORLEVEL 1 statement is true when the return code is any number equal to or greater than 1. However, I don’t
use this technique because programs can return negative numbers as well as positive numbers. Most programs rarely
document every possible return code, so I’d rather explicity check for non-zero with the NEQ 0 style than assuming
You may also want to check for specific error codes. For example, you can test that an executable program or script is
in your PATH by simply calling the program and checking for return code 9009.
SomeFile.exe
IF %ERRORLEVEL% EQU 9009 (
ECHO error - SomeFile.exe not found in your PATH
)
It’s hard to know this stuff upfront – I generally just use trial and error to figure out the best way to check the return
code of the program or script I’m calling. Remember, this is duct tape programming. It isn’t always pretty, but, it gets
There’s a super cool shorthand you can use to execute a second command based on the success or failure of a
command. The first program/script must conform to the convention of returning 0 on success and non-0 on failure for
this to work.
I use this technique heavily to halt a script when any error is encountered. By default, the command processor will
continue executing when an error is raised. You have to code for halting on error.
A very simple way to halt on error is to use the EXIT command with the /B switch (to exit the current batch script
context, and not the command prompt process). We also pass a specific non-zero return code from the failed
SomeCommand.exe || EXIT /B 1
A simliar technique uses the implicit GOTO label called :EOF (End-Of-File). Jumping to EOF in this way will exit your
I recommend sticking to zero for success and return codes that are positive values for DOS batch files. The positive
values are a good idea because other callers may use the IF ERRORLEVEL 1 syntax to check your script.
I also recommend documenting your possible return codes with easy to read SET statements at the top of your script
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
Note that I break my own convention here and use uppercase variable names – I do this to denote that the variable is
constant and should not be modified elsewhere. Too bad DOS doesn’t support constant values like Unix/Linux shells.
One small piece of polish I like is using return codes that are a power of 2.
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
SET /A ERROR_FILE_READ_ONLY=4
SET /A ERROR_UNKNOWN=8
This gives me the flexibility to bitwise OR multiple error numbers together if I want to record numerous problems in
one error code. This is rare for scripts intended for interactive use, but, it can be super helpful when writing scripts you
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SET /A errno=0
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_SOMECOMMAND_NOT_FOUND=2
SET /A ERROR_OTHERCOMMAND_FAILED=4
SomeCommand.exe
IF %ERRORLEVEL% NEQ 0 SET /A errno^|=%ERROR_SOMECOMMAND_NOT_FOUND%
OtherCommand.exe
IF %ERRORLEVEL% NEQ 0 (
SET /A errno^|=%ERROR_OTHERCOMMAND_FAILED%
)
EXIT /B %errno%
If both SomeCommand.exe and OtherCommand.exe fail, the return code will be the bitwise combination of 0x1 and
0x2, or decimal 3. This return code tells me that both errors were raised. Even better, I can repeatedly call the bitwise
OR with the same error code and still interpret which errors were raised.
File Numbers
Each of these three standard files, otherwise known as the standard streams, are referernced using the numbers 0, 1,
Redirection
A very common task in batch files is sending the output of a program to a log file. The > operator sends, or redirects,
stdout or stderr to another file. For example, you can write a listing of the current directory to a text file:
The > operator will overwrite the contents of temp.txt with stdout from the DIR command. The >> operator is a slight
variant that appends the output to a target file, rather than overwriting the target file.
A common technique is to use > to create/overwrite a log file, then use >> subsequently to append to the log file.
By default, the > and >> operators redirect stdout. You can redirect stderr by using the file number 2 in front of the
operator:
You can even combine the stdout and stderr streams using the file number and the & prefix:
This is useful if you want to write both stdout and stderr to a single log file.
To use the contents of a file as the input to a program, instead of typing the input from the keyboard, use
the <operator.
The pseudofile NUL is used to discard any output from a program. Here is an example of emulating the Unix
command sleep by calling ping against the loopback address. We redirect stdout to the NUL device to avoid printing
Let’s say you want to chain together the output of one program as input to another. This is known as “piping” output to
another program, and not suprisingly we use the pipe character | to get the job done. We’ll sort the output of the DIR
commmand.
DIR /B | SORT
You can quickly create a new text file, say maybe a batch script, from just the command line by redirecting the
command prompt’s own stdin, called CON, to a text file. When you are done typing, hit CTRL+Z, which sends the end-
There are a number of other special files on DOS that you can redirect, however, most are a bit dated like like LPT1 for
Or the converse:
IF EXIST "temp.txt" (
ECHO found
) ELSE (
ECHO not found
)
NOTE: It’s a good idea to always quote both operands (sides) of any IF check. This avoids nasty bugs when a variable
doesn’t exist, which causes the the operand to effectively disappear and cause a syntax error.
Or
IF "%var%"=="Hello, World!" (
ECHO found
)
IF /I "%var%"=="hello, world!" (
ECHO found
)
Artimetic Comparisons
SET /A var=1
The old-school way of looping on early versions of DOS was to use labels and GOTO statements. This isn’t used much
anymore, though it’s useful for looping through command line arguments.
:args
SET arg=%~1
ECHO %arg%
SHIFT
GOTO :args
The modern way to loop through files or text uses the FOR command. In my opinion, FOR is the single most powerful
GOTCHA: The FOR command uses a special variable syntax of % followed by a single letter, like %I. This syntax is
slightly different when FOR is used in a batch file, as it needs an extra percent symbol, or %%I. This is a very common
source of errors when writing scripts. Should your for loop exit with invalid syntax, be sure to check that you have
function keyword, you can fake it till you make it thanks to labels and the CALL keyword.
1. Your quasi functions need to be defined as labels at the bottom of your script.
2. The main logic of your script must have a EXIT /B [errorcode] statement. This keeps your main logic from falling
In this example, we’ll implement a poor man’s version of the *nix tee utility to write a message to both a file and the
stdout stream. We’ll use a variable global to the entire script, %log% in the function.
@ECHO OFF
SETLOCAL
Calling a function
We use the CALL keyword to invoke the quasi function labelled :tee. We can pass command line arguments just like
We have to remember to EXIT /B keyword at the end our function. Sadly, there is no way to return anything other
The return value of CALL will always be the exit code of the function. Like any other invokation of an executable, the
You have to get creative to pass anything other than integer return codes. The function can ECHO to stdout, letting the
caller decide to handle the output by pipeling the output as the input to another executable, redirecting to a file, or
The caller could also pass data by modifying a global variable, however, I try to avoid this approach.
Robust parsing of command line input separates a good script from a great script. I’ll share some tips on how I parse
input.
By far the easiest way to parse command line arguments is to read required arguments by ordinal position.
Here we get the full path to a local file passed as the first argument. We write an error message to stderr if the file does
SET filepath=%~f1
Optional parameters
SET filepath=%dp0\default.txt
Switches
Named Parameters
:confirm
SET /P "Continue [y/n]>" %confirm%
FINDSTR /I "^(y|n|yes|no)$" > NUL || GOTO: confirm
I use basic logging facilities in my scripts to support troubleshooting both during execution and after execution. I use
basic logging as a way to instrument what my scripts are doing at runtime and why. I remember watching a network
operations center trying to troubleshoot a legacy batch process where the sysadmins literrally had to try to read the
lines of a console window as they trickled by. This technique worked fine for years when the batch machines used dial-
up modems for connectivity to remote resources. However, the advent of brooadband meant the batch script executed
faster than anyone could read the output. A simple log file would have made troubleshooting work much easier for
these sysadmins.
Log function
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
This tee quasi function enable me to write output to the console as well as a log file. Here I am reusing the same log
file path, which is saved in the users %TEMP% folder as the name of the batch file with a .txt file extension.
If you need to retain logs for each execution, you could simply parse the %DATE% and %TIME% variables (with the
help of command line extensions) to generate a unique filename (or at least unique within 1-second resolution).
Taking a queue from the *nix world, I also like to include a prefix custom output from my own script as script:
some message. This technique drastically helps to sort who is complaining in the case of an error.
Displaying startup parameters
I also like to display the various runtime conditions for non-interactive scripts, like something that will be run on a
Sadly, I don’t know of any DOS tricks (yet) to discrimintate non-interactive sessions from interactive sessions. C# and
.Net has the System.Environment.UserInteractive property to detect if this situation; *nix has some tricks
with tty file descriptors. You could probably hack up a solution by inspecting a custom environmental variable
I like to include a header on all of scripts that documents the who/what/when/why/how. You can use the ::comment
:: Name: MyScript.cmd
:: Purpose: Configures the FooBar engine to run from a source control tree path
:: Author: [email protected]
:: Revision: March 2013 - initial version
:: April 2013 - added support for FooBar v2 switches
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
:: variables
SET me=%~n0
:END
ENDLOCAL
ECHO ON
@EXIT /B 0
The conditional operators || and && provide a convenient shorthand method to run a 2nd command based on the
The && syntax is the AND opeartor to invoke a 2nd command when the first command returns a zero (success) exit
code.
The || syntax is an OR operator to invoke a 2nd command when the first command returns a non-zero (failure) exit
code.
DIR myfile.txt >NUL 2>&1 || CALL :WARNING file not found - myfile.txt
We can even combined the techniques. Notice how we use the () grouping construct with && to run 2 commands
DIR myfile.txt >NUL 2>&1 || (ECHO %me%: WARNING - file not found - myfile.txt >2 &&
EXIT /B 1)
:: variables
PUSHD "%~dp0" >NUL && SET root=%CD% && POPD >NUL
You can use PING.EXE to fake a real *nix style sleep command.
Test if %CMDCMDLINE% is equal to %COMSPEC% If they are equal, we can assume that we are running in an interactive
session. If not equal, we can inject a PAUSE into the end of the script to show the output. You may also want to change
@ECHO OFF
SET interactive=0
ECHO do work
IF "%interactive%"=="0" PAUSE
EXIT /B 0
La sintaxis normal del comando FOR es:
Observa que la variable "var" ahora va precedida por dos simbolos de "%". Además, si este for está dentro
de un archivo BAT, el nombre de la variable debe ser UNA SOLA LETRA (p.ej: %%n, %%i, %%j , etc )
EJEMPLO1
Para que la variable del FOR vaya tomando distintos valores dentro de una lista determinada:
Esto sacará por pantalla las palabras que están entre parentesis, separadas linea a linea.
Y si el "for" está dentro de un archivo BAT, y tome los valores posicionales que se pasan cuando se llama
al archivo desde la consola:
EJEMPLO2
Si queremos recorrer una lista de archivos de un determinado directorio (solo archivos, no directorios):
for %f in (*) do (
echo %f
)
DIRECTORIOS:
FOR /D %V IN (lista) DO comando
Recorrer y mostrar todos los archivos de la unidad C: empezando en su directorio raiz, y recorriendo
recursivamente el resto de directorios que contiene:
Una variacion de este ejemplo sería el buscar un determinado tipo de archivos dentro de un directorio
recursivamente. Voy a buscar todos los archivos "dll" y "exe" dentro del directorio "windows":
for /D %v in (*) do (
echo %v
)
for /R /D %v in (*) do (
echo %v
)
Y saltando de 2 en 2
Y de 3 en 3:
etc.
Hay que observar que el primer numero dentro del parentesis es el valor inicial que tomará la variable
"%x", el segundo numero es el incremento que sufrirá dicha variable en la proxima iteracion del FOR, y el
tercer número es el valor máximo que tomará dicha variable y que cuando alcance o supere dicho valor, el
bucle FOR terminará de ejecutarse.
EJEMPLO6:
Archivo BAT que crea varios archivos vacios y los llama a todos con el mismo nombre, pero terminados en
un numero diferente:
@echo off
cls
El FOR va recorriendo todas las lineas, y cada linea se ha dividido en "tokens" (token=palabra). La
variable del for almacena la primera palabra de cada linea.
EJEMPLO8: (parametro /F con tokens)
Podemos seleccionar varios tokens mediante la clausula tokens=. Los distintos tokens se irán guardando
automáticamente en variables alfabeticamente consecutivas a partir de la variable creada en el for.
En el siguiente ejemplo nos quedamos con los tokens (palabras) 1, 3 y 5 de cada linea:
observa que aunque yo solamente he definido la variable "%%a" en el FOR, las variables "b" y "c" se
crean automaticamente.
Podemos escoger rangos, como en el siguiente ejemplo, en el que vamos a escoger los tokens del 1 al 3,
y además el token 5
Además de la clausula "tokens" con el parámetro "/F", podemos usar la clausula "delims", que indica la
separacion entre los distintos tokens. Por defecto, los caracteres delimitadores entre tokens son los
espacios en blanco y los tabuladores.
Si queremos usar como delimitadores los simbolos de puntuacion, como el punto, la coma, el punto y
coma, etc...:
esto solo imprimirá por pantalla la linea completa hasta que encuentre alguno de los delimitadores que le
hemos indicado.
skip=n, que se saltaría las n primeras líneas del archivo, empezando a procesar la n+1
eol=carácter, que interpreta las líneas que comienzan por ese carácter como líneas de
comentarios y se las salta.
useback, que cambia la semantica de la lista: (`comando`), ('cadena'), (archivo) ("archivo1"
"archivo2" "archivo3")
Se puede sustituir la lista de valores que tiene que tomar la variable, por la ejecución de un comando,
como en el siguiente ejemplo:
Observar el caracter de escape "^" necesario para que la tubería se interprete dentro del comando en vez
de ser interpretado para el for
Podemos extraer distintas partes del valor de una variable. Por ejemplo, si mostramos el valor de la
variable "date", nos dará una fecha con el siguiente formato:
07/05/2012
donde el dia, la fecha y la hora están separados por un carácter que sirve de delimitador: "/"
Para extraer las distintas partes de la fecha utilizamos el siguiente ejemplo (dentro de un archivo BAT):
Para poder acceder a dichas variables hay que poner al principio del archivo BAT la siguiente linea (es
MUY MUY IMPORTANTE ponerlo, porque sino no funcionará bien nuestro programa BAT):
setlocal enabledelayedexpansion
y además para acceder al valor de dichas variables hay que usar el simbolo de admiración "!", en lugar del
simbolo "%"
Por ejemplo, el siguiente archivo BAT nos muestra la tabla de multiplicar de un numero que yo le indique
por teclado:
tabla.bat
@echo off
cls
setlocal enabledelayedexpansion
Si quiero ver todas las tablas de multiplicar, debo anidar un FOR dentro de otro, y el archivo BAT quedaría
así:
todastablas.bat
@echo off
cls
setlocal enabledelayedexpansion
)
pause
cls
)
cmd /v:on
Aquí iré añadiendo, cuando tenga tiempo, las soluciones a lo que me vais planteando los que comentais
en esta entrada.
SOLUCIÓN:
@echo off
cls
dir
echo.
cls
rem ahora con el siguiente "for" extraigo (con el comando "find") la unica
linea donde estan los caracteres "/" del listado que me saca el comando dir,
porque ahi esta la fecha que quiero obtener
rem y tambien es muy importante poner el acento circunflejo "^" justo antes del
caracter filtro "|", porque sino no funcionara
"Quiero recorrer a partir de un directorio todos los archivos y renombrar los que tienen una extension, por
ejemplo jpg
tendria que renombrar todos incusive si hay subdirectorios."
Esto NO SE PUEDE HACER, porque a cada archivo le tendrías que poner un nombre diferente (no puede
haber 2 o más archivos que tengan el mismo nombre y la misma extensión), tendrías que ir cambiandoselo
uno por uno.
Sin embargo, si puedo cambiar la extensión de todos los archivos de un determinado directorio, que
tengan una extensión en concreto (por ejemplo ".avi", ".mp3", o cualquier otra), este sería el archivo BAT:
SOLUCION
@echo off
setlocal enabledelayedexpansion
cls
echo Este archivo BAT recorre un directorio y sus subdirectorios y renombra los
archivos que tengan una determinada extension:
echo.
echo.
set /p dir="Introduce la ruta del directorio:"
set /p ext="Introduce la extension de los archivos que se van a cambiar:"
set /p nueva="Introduce la nueva extensión que van a tener esos archivos:"
echo.
echo.
rem Con el siguiente "for" me voy metiendo en los subdirectorios del directorio
actual y les voy cambiando la extension a los archivos elegidos
"Quiero hacer un archivo BAT que: Programe la ejecución de una copia de seguridad del contenido de una
carpeta a otra a la hora que se pase como parámetro."
SOLUCION:
Aqui hay que preguntar 3 cosas al usuario: la carpeta que quiere copiar, la carpeta destino, y la hora a la
que se efectuará esa copia. Y después usar el comando "at" para programar la tarea a una hora
determinada, y el comando "xcopy" para copiar un directorio con todo su contenido.
@echo off
cls
set /p origen="Escribe la ruta de la carpeta que quieres copiar:"
set /p destino="Escribe la ruta de destino"
set /p hora="Escribe la hora a la que se hara esta copia: hh:mm"
at %hora% xcopy %origen% %destino%
@echo off
cls
set /p origen="Escribe la ruta de la carpeta que quieres copiar:"
set /p destino="Escribe la ruta de destino"
"Quiero hacer un archivo BAT que: Muestre el nombre y tamaño de los archivos de la carpeta
activa cuyo tamaño sea superior a la cantidad que se indique como parámetro"
SOLUCION:
Con un for hay que ir recorriendo todos los archivos del directorio actual, y comparar su tamaño con el
número de bytes que se le ha pasado como parametro posicional número 1 (%1).
@echo off
set enabledelayedexpansion
cls
"Quiero hacer un archivo BAT que: me muestre la linea numero 4 de un archivo en concreto"
He hecho un archivo bat mejor que te pida el nombre de un archivo, y una linea inicial y una final y te
imprima todas las lineas que están entre ambos numeros
SOLUCION:
@echo off
cls
setlocal enabledelayedexpansion
set num=1
"Quiero hacer un archivo BAT que me muestre las 30 ultimas lineas de un archivo en concreto"
He hecho un archivo bat mejor que te pida el nombre de un archivo, y las lineas finales, y te imprima las
lineas finales que el usuario indique
SOLUCION:
@echo off
cls
setlocal enabledelayedexpansion
archivo:
set num=1
echo El archivo %nombre% tiene %num% lineas. Las ultimas %lineas% lineas son
las siguientes:
echo.
echo.
REM En la variable inicio estara el numero de la linea desde la que tenemos que
imprimir por pantalla
set /a inicio = !num! - !lineas!
set num=1
"Quiero hacer un archivo BAT que lea un fichero que tiene un indice (un numero al principio de cada linea)
y que las lineas que estan entre 0 y 249 las guarde dentro de un archivo (archivo1.txt) y las restantes
lineas las guarde en otro archivo (archivo2.txt)"
SOLUCION:
@echo off
cls
setlocal enabledelayedexpansion
"Quiero hacer un archivo BAT que recorra el árbol que cuelga de un directorio, y me copie un archivo
determinado en cada uno de los directorios de dicho árbol"
SOLUCION:
@echo off
"Quiero hacer un archivo BAT que sume los datos numericos que se encuentran en las lineas de un fichero
de texto. Estos numeros tienen separador de miles"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set suma=0
echo ------------------------
echo !suma!
pause
@echo off
cls
setlocal enabledelayedexpansion
set suma=0
echo ------------------------
echo !suma!
pause
"Quiero hacer un archivo BAT que copie el ultimo archivo modificado a un directorio"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set num=1
"Quiero hacer un archivo BAT que extraiga un caracter de una variable usando un FOR"
En los lenguajes de programación como Pascal, Java, C, etc. , existen funciones específicas que sirven
para extraer una subcadena que se encuentre dentro de una cadena de caracteres, pero en la
programación de archivos BAT no hay ningún comando que haga esto directamente (o por lo menos yo no
lo conozco).
Se puede hacer una especie de bucle (usando etiquetas e instrucciones goto) que vayan pasando por el
primer caracter de una variable ( usando " echo %variable:~0,1% " ) y lo vayamos desplazando un lugar
hacia la izquierda ( usando " set variable=%variable:~1% " ). Así haremos que se vayan imprimiendo por
pantalla todos los caracteres de la variable, linea por linea.
SOLUCIÓN:
@echo off
setlocal enabledelayedexpansion
cls
:bucle
set letra=%frase:~0,1%
set frase=%frase:~1%
goto bucle
:fin
pause
"Quiero hacer un archivo BAT que elija el archivo de mayor tamaño de un mes y un año concretos, cuyo
nombre empiece por TARRO.D[fecha]"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set num=1
"Quiero hacer un archivo BAT que me cree automaticamente carpetas para cada dia del mes de un
determinado año, para guardar las fotos que voy haciendo en ellas, clasificadas por días"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set /p mes="Escribe el mes : "
set /p anio="Escribe el anio : "
86134 31965 01706 10304 20243 30011 40096 53006 61254 70500 333 10377 55103=
86170 32970 01604 10286 20203 39988 40089 53003=
86185 NIL=
86192 32970 00000 10282 20183 39895 40109 63204 52004=
86210 32570 11802 10302 20225 39769 40103 52020 81200 333 10374 55110
81833=
86218 31960 01504 10284 20219 30021 40116 53005 70400
55103=
en el que cada linea termina en el caracter "=". Quiero obtener aquellos valores de cada linea que
empiecen por un numero concreto"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set /p num=Por que digito empiezan los numeros que estas buscando? (0-9) :
000001 texto
000003 texto
000004 texto
000007 texto
..
en el que cada linea empieza por un numero de 6 digitos rellenado con ceros a la izquierda. Los numeros
de esas lineas no son correlativos. ¿Como podría corregirlos automaticamente para que si lo fueran?"
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
set relleno=000000
set num=1
pause
"Tengo varios archivos de texto, que contienen información. Quiero extraer automaticamente de cada uno
de ellos las lineas que están entre las cadenas de caracteres "DISPENSER ERROR" y "RCLen".
He creado un archivo bat para extraer esas lineas de un archivo llamado "datos2.txt", aqui está la
solución:
SOLUCIÓN:
@echo off
cls
setlocal enabledelayedexpansion
+2') do (
set inicio=%%a
)
set inicio=!inicio:~1!
set ini=
:bucle1
set ini=!ini!!inicio:~0,1!
set inicio=!inicio:~1!
goto bucle1
:continuar
set fin=!fin:~1!
set final=
:bucle2
if "!fin:~0,1!" == "]" goto :continuar2
set final=!final!!fin:~0,1!
set fin=!fin:~1!
goto bucle2
:continuar2
set num=1