Copying files in cmd

The old, venerable Windows cmd command prompt is always on hand for quick and dirty tasks. Today, we'll use it to copy files around.

Selecting Files

If you can specify the files you want to copy with a simple mask, you have plenty of built-in support.

The copy command is your basic tool to copy files around.

The xcopy command adds the ability to copy subdirectories recursively.

Finally, robocopy is the supercharged file copier. Yes it handles subdirectories, but it allows customizing file and security attributes, restartable network mode, and some basic options for synchronization.

Sometimes, however, we have a very specific set of files to work with and checking things by hand comes in handy.

Iterating

So, let's say we want to copy a handful of .dlls from under a directory tree. We can get a basic list of files like so.

dir /s /b the-directory\*.dll > %temp%\files.txt

The flags we're using are /s to recurse in subdirectories, \b for bare full-path filenames, and the *dll mask will apply at every recursed directory.

We pipe that to a temporary file, and now we can review manually.

For extra bonus, we'll allow ourselves to delete some of the files, or add comments prefixed with # - as is tradition.

Now, let's turn to our very powerful but syntactically tricky friend, for.

Let's look at some of the highlights in the documentation that will help us.

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]

    file-set is one or more file names.  Each file is opened, read
    and processed before going on to the next file in file-set.
    Processing consists of reading in the file, breaking it up into
    individual lines of text and then parsing each line into zero or
    more tokens.  The body of the for loop is then called with the
    variable value(s) set to the found token string(s).  By default, /F
    passes the first blank separated token from each line of each file.
    Blank lines are skipped.  You can override the default parsing
    behavior by specifying the optional "options" parameter.  This
    is a quoted string which contains one or more keywords to specify
    different parsing options.  The keywords are:

        eol=c           - specifies an end of line comment character
                          (just one)
        skip=n          - specifies the number of lines to skip at the
                          beginning of the file.
        delims=xxx      - specifies a delimiter set.  This replaces the
                          default delimiter set of space and tab.
        tokens=x,y,m-n  - specifies which tokens from each line are to
                          be passed to the for body for each iteration.
                          This will cause additional variable names to
                          be allocated.  The m-n form is a range,
                          specifying the mth through the nth tokens.  If
                          the last character in the tokens= string is an
                          asterisk, then an additional variable is
                          allocated and receives the remaining text on
                          the line after the last token parsed.

Based on this, here are the options we'd like to use:

rem print out the commands we're going to run
@FOR /F "eol=#" %i IN (%temp%\files.txt) DO @echo copy /y %i %copy_target%

rem now run them for real
@FOR /F "eol=#" %i IN (%temp%\files.txt) DO copy /y %i %copy_target%

skip would be useful for a header in a tab separate file, but we don't need it here.

tokens would also be handy to either read "all other text" or to pick specific values from a file.

Happy file copying!

Tags:  shell

Home