I have identical files in four folders (named "1", "2", "3", "4") and would like to copy these files into a single folder, with the original folder name appended to the filename.
E.g. a file called "data.txt" in each folder should be copied to a new merged folder, with filenames such as "data 1.txt" "data 2.txt" etc.
Here is what I have so far, but I never formally learned batch scripting (and can't find any decent tutorials - recommendations please?) and can't seem to make it work. Hopefully this gives an idea of what I want to accomplish.
DIR="$( dirname "$0" )" && pwd )" // I don't understand this but was told it's
// necessary to set the working directory as
// the current folder? Is that correct?
md "consolidated files"
for %%i in ("1","2","3","4") do
copy *.txt '../consolidated files/"*"+%%i.txt'
Any tips for a beginner? Thanks!
@ECHO OFF
SETLOCAL
PUSHD "U:\sourcedir"
MD "consolidated files" 2>nul
for %%i in ("1","2","3","4") DO (
FOR /f "delims=" %%m IN ('dir /b /a-d ".\%%~i\*.txt"') DO (
copy ".\%%~i\%%m" ".\consolidated files\%%~nm %%~i%%~xm"
)
)
popd
GOTO :EOF
Your attempt to set dir
appears to be a bash command - useful on *nix but no good on CMD
.
Essentially, you can set the current directory using cd
cd "c:\your\desired directory"
Quirkishly, the quotes in that particular command are actually unnecessary (but do no harm, so I put them in.)
Another approach is
pushd "c:\your\desired directory"
rem commands following have current directory "c:\your\desired directory"
rem
popd
rem current directory reestored to value before the "pushd"
I've used the second approach in the above script to switch temporarily to my test directory U:\sourcedir
Note that cmd
uses \
as a directory-separator and /
as a switch-indicator.
The md
command is as you had it. The directory is created relative to the current directory unless the path is specified (eg md "C:\somewhere new"). The
2>nulsuppresses the
directory already exists` message should the directory er, already exist.
in a for...do
statement, either the target operation must be on the same line as the do
or the do
must be followed by Space( and then each statement until a matching )
is executed as a compound statement.
The for..%%i
statement assigns the values "1"
.."4"
(including the quotes) to %%i
The quotes are actually not required in this case - they only need to be there if the required string includes a Space (or other separator.)
The next command is best understood from the middle. The dir
command looks in ".\%%~i\" for files named *.txt
. ~i
means "remove quotes from %%i". The /b
switch shows just filenames - no size, date or header/footer. The /a-d
switch says 'no directories'.
This dir
command is within single-quotes. FOR /f ...('single-quoted command')...
processes the result of the command as if it was a file, line-by-line. The "delims="
suppresses the default tokenising of the strings found, so overall, the filenames found by the dir
are assigned to %%m
in their entirity.
The command then executed is the copy
, copying from ".\%%~i\%%m"
(ie. the current directory++the subdirectory(-quotes)++filename; all quoted in case of spaces) to ".\consolidated files\%%~nm %%~i%%~xm"
(ie. the current directory+\consolidated files+the name part of the filename (%%~nm)+Space+the subdirectory(-quotes)+the extension part of the filename (%%~xm))
Note that +
is a valid filename character (as is '
) and that strings are built simply by being butted up one against the next.
Your original question stated that the source directoryname should be appended after a space, hence I've included the space.
Note that copy
will report 1 file(s) copied
after each copy. You can suppress this by adding >nul
to the end of the copy
statement.
For testing, I would change copy
to echo copy
which will show the command generated but not execute it. Unfortunately, if you have the >nul
in place, the echo
of the command will be suppressed...