--
Tumbleweed
email replies not necessary but to contact use;
tumbleweednews at hotmail dot com
Enumerate the subset directory
FOR %a in (Drive:\subset\*) Do ...
Then use the special tilde operator (~) that selects the filename and
extension only; append that filename to the original path and copy it to the
new destination
@Copy Drive:\original\%~nxa Drive:\newsubset
On the commandline use '%a', in a script use '%%a'.
Frank
Thanks frank, what do/does the "nxa" do after the tilde?
I have only every used copy in its simplest form from the command line.
If it makes any difference, the files are binary (JPEGS) and most names are
not in 8.3 format. I suppose I should have said, XP SP2 but I presume thats
not critical?
> Thanks frank, what do/does the "nxa" do after the tilde?
FOR /?
One of the many ~ examples:
http://www.netikka.net/tsneti/info/tscmd012.htm#continue
All the best, Timo
--
Prof. Timo Salmi mailto:t...@uwasa.fi ftp & http://garbo.uwasa.fi/
Hpage: http://www.uwasa.fi/laskentatoimi/english/personnel/salmitimo/
Department of Accounting and Finance, University of Vaasa, Finland
Useful CMD script tricks http://www.netikka.net/tsneti/info/tscmd.htm
Ah that takes some burrowing to find - and in my naivety I had done a /?,
but for COPY, not for 'FOR' :-)
So this is what I have to be typed on the cmmand line?
FOR %a in G:\subset\* DO
@Copy G:\ORiginal\%~nxa G:\NewSubset
Does that look good?
Bear in mind this is my first time doing anything that involves typing more
than single line commands :-)
> So this is what I have to be typed on the cmmand line?
>
> FOR %a in G:\subset\* DO
> @Copy G:\ORiginal\%~nxa G:\NewSubset
>
>
> Does that look good?
> Bear in mind this is my first time doing anything that involves typing more
> than single line commands :-)
>
Not exactly - you missed the parentheses. If there might be spaces in file
names you better use quotes.
FOR %a in (G:\subset\*) DO @XCopy "G:\ORiginal\%~nxa" "G:\NewSubset\"
- xcopy should be faster
- the trailing backslash in the destination should avoid the question
if dest is a file or a folder
--
HTH
Matthias
Assuming that your originals are in C:\originals and your altered files are
in c:\altered and your new subset will appear in c:\newsubset then
xcopy /s /e /v "c:\altered\*" "c:\newsubset\"
xcopy /u /s /e /v "c:\originals\*" "c:\newsubset\"
should do the job. You will have to reply "a" to the Overwrite prompt on the
second command.
The first copies the tree that has been selected and potentially altered
into a brand-new directory-tree.
The second command uses the characteristic of the /u switch on the XCOPY
command to then overwrite the filenames that were selected into the
c:\altered tree with those from the matching name in c:\originals.
First time I've ever found a use for xcopy's /u switch.
CAUTION : it may be prudent to add the /L switch into the xcopy commands,
which will REPORT what is intended to be done. Remove the /L switch to
actually do the XCOPY.
OP: The up-arrow will return previous commands; then left/right arrows to
position the cursor, the del key will delete characters as you may imagine.
In standard mode, character keys typed will be inserted into the command
(enter key executes) by default; the insert key toggles between insert and
overtype (it is possible to start in overtype rather than insert mode.)
Before this goes any further, I believe that a significant point has been
missed - or I've missed something (and that's been known to happen :))
There is specific mention of a tree structure - I'll quote from the original
(one of the evils of snipping :))
"The subset have the same directory structure and file names as the
original, and its only 1 level deep, eg its basically multiple folders under
a top level folder"
So, what I believe is required is not a simple scan of a single directory,
but a substantially more involved scan of a two-level subtree.
Whereas I prefer the simplicity of the two-line solution I've already
posted, my solution was:
This solution developed using XP
----- batch begins -------
[1]@echo off
[2]setlocal enabledelayedexpansion
[3]md "C:\destdir" 2>nul
[4]for /f "delims=" %%i in ( ' dir /s /b /a-d c:\tumbleweed ' ) do (
[5] set filename=%%i
[6] set filename=!filename:~14!
[7] echo f|xcopy "c:\sourcedir\!filename!" "C:\destdir\!filename!"
>>tumble.txt
[8])
------ batch ends --------
Lines start [number] - any lines not starting [number] have been wrapped and
should be rejoined. The [number] that starts the line should be removed
The spaces surrounding the single-quotes are for emphasis only. The SPACES
are not required but the single-quotes ARE required.
%varname% will be evaluated as the value of VARNAME at the time that the
line is PARSED. The ENABLEDELAYEDEXPANSION option to SETLOCAL causes
!varname! to be evaluated as the CURRENT value of VARNAME - that is, as
modified by the operation of the FOR
Where c:\tumbleweed was the altered directory, c:\sourcedir the unaltered
source and c:\destdir the new directory. In [6] the magic "14" is the length
of the 'c:\tumbleweed\" string. ">>tumble.txt" is simply an output text
report file (and it'll be UGLY) and could have been replaced by ">nul" if no
report is required.
But I may have read it wrong.
Mathias you are correct, there is 'Top Level Directory', and under that a
number of sub directories, eg Directory1, Directory2, etc. The files of
interest (all 1500 of them in the subset and maybe 10x that in the
originals) are in Directory1, Directory2 etc. There are no files in 'Top
Level Directory', and there is no further nesting below the first level of
directories.
I presume this explains why I couldn't get the original solution to work ,
it doesn't work its way down the directory tree?
Can you explain what line 6 is doing please?
Yes - that would be right.
I'd suggest that you use my other solution, though. Two lines and the pain's
all over.
You would need to save this file as anynameyouchoose.bat, then simply invoke
the bat from the prompt by typing anynameyouchoose.
The changes you would need to make are : change the directory names as
appropriate and change the "14" in [6] to (the length of the directoryname
that you are using as the subset-that-may-have-been-changed) +1. Since I
used "C:\tumbleweed" for my testing, this has a length of 13, add 1 = 14.
Why? Normally, %varname% gets the content of the environment variable
VARNAME. Within a FOR loop however, %varname% refers to the PARSE-TIME value
of VARNAME, so line [2] invokes "delayed expansion" mode, where !varname!
returns the RUN-TIME value of VARNAME, as it changes in the loop.
So - %%i (the loop-control metavariable) gets assigned each filename in
turn - the ' "delims=" ' part assigns the entire line of output of the DIR
command to %%i
* you could try the DIR command in the quotes directly from the prompt
(without the quotes) - /s gives subdirectories, /b in basic mode (no
headers, etc) and /a-d suppresses directory names
[5] assigns the value of the metavariable to the environment variable
FILENAME
[6] then re-assigns FILENAME as the NEW value of filename, starting at the
14th character, counting from 0 as the first, C-style. The ':~m,n' is used
to substring, m being the start position and n being the length required -
see
SET /?
from the prompt for docco
(You can't use substringing directly on a metavariable)
[7] forces a reply of "f" to the prompt generated by XCOPY, enquiring
whether the destination name is a file or a directory. I used XCOPY because
it will create a directory tree if required whereas COPY does not.
Unfortunately, there isn't a "this is a filename" switch for XCOPY.
One last little notion - it's probably better to use EDIT from the prompt to
create a batch - possibly from a cut-and-paste from Notepad. Notepad
sometimes likes doing formatting, which plays havoc with batch.
But, I'll say again, my other solution is probably better.
Thanks a lot, have tested the two liner on a sub-subset of the files and it
works perfectly so will use that one.
Thanks guys just to confirm that worked perfectly, now I have a follow up Q
:-)
Now I have my 'master' set of files fixed up, what I want to do is 'sync'
that to a copy set. I will occasionally add new files to the master set, and
then once in a while want to run a job that will only copy new and altered
files in the master set, into/over the 'sync set' (which are on a seperate
device thats not connected most of the time). Worst case I can just
overwrite the entire "sync set" as its only a few GB, but it seems more
"elegant" to only copy new/altered files.
TIA
Ah, answer my own Q, XCOPY /D