7. Files & Folders¶
What & why¶
Most batch scripts exist to move files around: copy build output, archive logs, clean temp folders. This lesson covers the file commands, their failure modes, and when to reach for robocopy instead.
Making and removing folders¶
md "C:\work\output" &rem make; creates intermediate folders too
mkdir "C:\work\a\b\c" &rem md and mkdir are the same
rd "C:\work\output" &rem remove — only if empty
rd /s /q "C:\work\output" &rem /s recurse, /q no "Are you sure?" prompt
rd /s /q is irreversible
It does not use the Recycle Bin. There is no undo. Double-check the path — especially if it's built from a variable that could be empty (rd /s /q "%target%\" with empty %target% becomes rd /s /q "\" = the drive root). Guard it:
Copying¶
copy "src.txt" "dst.txt" &rem single file
copy "src.txt" "C:\backup\" &rem into a folder (keep name)
copy "*.log" "C:\archive\" &rem multiple files
copy /y "src.txt" "dst.txt" &rem /y = overwrite without prompting
type a.txt b.txt > combined.txt &rem concatenate
copy does not create missing destination folders and does not recurse.
xcopy — folders and trees¶
| Switch | Meaning |
|---|---|
/E |
copy all subfolders, including empty ones (/S skips empty) |
/I |
assume destination is a folder if it doesn't exist |
/Y |
overwrite without prompting |
/D |
only copy files newer than the destination |
/EXCLUDE:file |
skip paths listed in file |
robocopy — the good one¶
For anything nontrivial (mirroring, retries, logging, large trees), use robocopy:
| Switch | Meaning |
|---|---|
/MIR |
mirror: copy new/changed, delete extras in destination |
/E |
subfolders including empty (safer than /MIR — no deletes) |
/R:2 |
retry 2 times on a locked file (default is 1 million — set this!) |
/W:5 |
wait 5 seconds between retries |
/NP |
no per-file percentage spam |
/LOG: / /TEE |
write a log / also show on console |
/XD /XF |
exclude dirs / files |
robocopy exit codes are not 0/1
robocopy returns a bitmask: 0 = nothing to do, 1 = files copied, 2 = extra files, 3 = 1+2, ... anything ≥ 8 is a real error. So:
if errorlevel 1 treats a successful copy as failure.
Moving and renaming¶
move "old\report.txt" "new\report.txt"
move /y "*.tmp" "C:\trash\"
ren "report.txt" "report-2026.txt" &rem rename in place; ren cannot move
ren "*.txt" "*.bak" &rem bulk rename by extension
Deleting files¶
del "temp.txt"
del /q "*.tmp" &rem /q quiet (no wildcard confirm prompt)
del /f /q "readonly.txt" &rem /f force read-only
del /s /q "C:\build\*.obj" &rem recurse
del removes files, not folders. It does not use the Recycle Bin.
Listing¶
dir &rem full listing
dir /b &rem bare: names only, one per line
dir /b /s "*.txt" &rem bare + recurse = full paths, great for for /F
dir /a:d /b &rem directories only
dir /a:-d /b &rem files only
dir /o:-d &rem sort by date descending
dir /b /s *.log | find /c /v "" &rem count matching files
dir /b /s piped into for /F is the standard "find all files matching X" idiom.
Checking existence and attributes¶
if exist "report.txt" echo present
if exist "C:\logs\" echo folder present
attrib "file.txt" &rem show attributes
attrib +r "file.txt" &rem set read-only
attrib -r -h "file.txt" &rem clear read-only and hidden
Common mistakes¶
rd /s /qwith an empty variable wiping a drive root. Always guard the path.- Trusting
robocopyexit codes like a normal command — useif %errorlevel% geq 8. robocopywithout/R:n— one locked file = a million retries = your script hangs "forever."copynot creating folders —mdthe destination first.del *.tmpprompting in a scheduled job with no console — add/q.rento move a file — it can't; usemove.moveoverwriting silently without/yin scripts, or prompting and hanging with a console — decide and be explicit.- Wildcards matching more than you think —
del log*also deleteslogin.config. Be specific.
Exercises¶
- Write
mkbak.bat SRCthat copiesSRCtoSRC.bak(use%~1), overwriting if it exists, and printsBacked upor an error ifSRCdoesn't exist. - Write a script that creates
demo\a,demo\b,demo\c, drops an empty.txtin each, then lists them withdir /b /s. - Mirror
demotodemo-mirrorwithrobocopy /E /R:1 /W:1and report success/failure using the>= 8rule. - Bulk-rename every
.login a folder to.log.oldwith onerencommand. - Recursively delete every
.tmpunder%TEMP%\myapp(create some first), quietly, and print how many were left (dir /b /s *.tmp | find /c /v ""). - Guard a
rd /s /q "%target%"so it refuses to run whentargetis empty or not an existing folder.
Recap¶
mdcreates (with intermediate dirs);rd /s /qremoves recursively with no undo — guard the path.copy= single files/no recursion;xcopy /E /I /Y= trees;robocopy= anything serious (/R:2 /W:5, checkerrorlevel >= 8).movemoves/renames,renrenames only,delremoves files only — none use the Recycle Bin.dir /b /s pattern→for /Fis the find-files idiom.
Next: Redirection & pipes →