Question

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!

Was it helpful?

Solution

@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"). The2>nulsuppresses thedirectory 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...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top