Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

How to? Copy /o to two directories?

Hi. Using TC/TCC 19.10.54 x64 on Windows 10. In my Windows startup .btm file, I have this line:

Code:
copy /o C:\path1\* \\%NAS\path2\*.jpg

to copy any new files in path1 (they are .jpg files, but have no extension) to path2 on the NAS, giving them a .jpg extension. So, path2 contains a copy of all the files in path1, and the two paths contain a large number of files. I would like to have any new files that are copied to path2, to also be copied to path3 (which is normally empty), so that I can quickly determine and act on files that are new:

Code:
copy /o C:\path1\* \\%NAS\path2\*.jpg AND \\%NAS\path3\*.jpg

Obviously this can't be done with a single copy command as above. How can it be done?
 
In general, you CAN specify multiple destinations. This little test worked.

Code:
v:\> md dir1 dir2

v:\> touch /c noextension
2022-02-14 13:10:31.990  V:\noextension

v:\> copy /o v:\noe* to: v:\dir1\*.jpg v:\dir2\*.jpg
V:\noextension => V:\dir1\noextension.jpg
V:\noextension => V:\dir2\noextension.jpg
     2 files copied
 
P.S., ... and failed when I tried it a second time (as expected since the destination files already existed).
 
Since you only want to act on the new files, copying them twice seems like an extra step.
Code:
do f in /p copy /ns /o C:\path1\* \\%NAS\path2\*.jpg (echo %@word["=>",1,%f])

The above will display the names of the destination files. From there you can copy the names to the clipboard or a file and act on them one at a time.
Code:
(do f in /p copy /ns /n /o C:\path1\* \\%NAS\path2\*.jpg (echo %@word["=>",1,%f])) > clip:
do f in @clip: (echo somecommand %f)
 
Alternatively, you can do something like this:
Code:
do f in C:\path1\* (if not exist \\%NAS\path2\%f.jpg somecommand %f)
 
In general, you CAN specify multiple destinations. This little test worked.

Code:
v:\> md dir1 dir2

v:\> touch /c noextension
2022-02-14 13:10:31.990  V:\noextension

v:\> copy /o v:\noe* to: v:\dir1\*.jpg v:\dir2\*.jpg
V:\noextension => V:\dir1\noextension.jpg
V:\noextension => V:\dir2\noextension.jpg
     2 files copied
Hmm... for me, this resulted in all files from v:\ (my path1) being copied to v:\dir2 (my path3). The desired result is for dir1 (my path2) to contain everything that is in v:\ (my path1), but for dir2 (my path3) to contain only new files that were added to dir1 (my path2).
 
Last edited:
Alternatively, you can do something like this:
Code:
do f in C:\path1\* (if not exist \\%NAS\path2\%f.jpg somecommand %f)
This seems to be close but, substituting the copy command for somecommand above, TCC is inserting the entire source path after the destination path. What does 'f' (and '%f') contain: is it the individual filename within the source path, or is it the entire source path/filename?
 
This seems to be close but, substituting the copy command for somecommand above, TCC is inserting the entire source path after the destination path. What does 'f' (and '%f') contain: is it the individual filename within the source path, or is it the entire source path/filename?
Thanks Scott.

Using the echo command, it seems that %f contains the entire path/filename, so therefore that path/filename of course does not exits in the destination path.

do f in path1\* (echo %f) shows %f contains the entire path/filename for each file in path1; therefore (if not exist path2\%f.jpg) will be interpreted as (if not exist path2\path1\filename.jpg) which will always fail.

So I need to be able to get just the filename from within the path1\filename that is in %f.

This works (hooray):

cd C:\path1\
do f in * (if not exist \\%NAS\path2\%f.jpg copy %f to: \\%NAS\path2\%f.jpg \\%NAS\path3\%f.jpg)

but it requires that I first change the working directory. If would be nicer if something like this would work:

do f in C:\path1\ [full path\filename] (if not exist \\%NAS\path2\%g.jpg [filename only of %f] copy %f to: \\%NAS\path2\%g.jpg \\%NAS\path3\%g.jpg

So, how to get g% (filename only) from %f (full path\filename)?

Okay, so this seems to work:

do f in C:\path1\* (if not exist \\%NAS\path2\%@filename["%f"].jpg copy %f to: \\%NAS\path2\%@filename["%f"].jpg \\%NAS\path3\%@filename["%f"].jpg

Can this be improved upon? Perhaps by using 'set' instead of multiple '%@filename[]' as Vince suggested?
 
Last edited:
Hmmm! Multiple COPY destinations WAS a feature of v19. And it seems to work here.

Code:
v:\> ver
TCC 19.10.54 x64
Microsoft Windows 10 Pro for Workstations
10.0.19044.1526 (2009, 21H2)

v:\> copy /o v:\noe* to: v:\dir1\*.jpg v:\dir2\*.jpg
V:\noextension => V:\dir1\noextension.jpg
V:\noextension => V:\dir2\noextension.jpg
     2 files copied
 
Hmmm! Multiple COPY destinations WAS a feature of v19. And it seems to work here.

Code:
v:\> ver
TCC 19.10.54 x64
Microsoft Windows 10 Pro for Workstations
10.0.19044.1526 (2009, 21H2)

v:\> copy /o v:\noe* to: v:\dir1\*.jpg v:\dir2\*.jpg
V:\noextension => V:\dir1\noextension.jpg
V:\noextension => V:\dir2\noextension.jpg
     2 files copied
But what happens if you have several files in v:\ and in dir1, but dir2 is empty? And you then add a new file to v:. Then the new file in v: gets copied to dir1 (correct), but (for me) all of the files from v: get copied to dir2, whereas what I want is for only the new file to get copied to dir2.
 
But what happens if you have several files in v:\ and in dir1, but dir2 is empty? And you then add a new file to v:. Then the new file in v: gets copied to dir1 (correct), but (for me) all of the files from v: get copied to dir2, whereas what I want is for only the new file to get copied to dir2.
That's how the /O switch works. You probably need a different strategy. Scott's suggestion looks pretty good.

Code:
do file in source_dir\*
    set jpgname=%@filename[%file].jpg
    iff not exist dest_dir_1\%jpgname then
        copy %file dest_dir_1\%jpgname
        copy %file dest_dir_2\%jpgname
    endiff
enddo

[or something like that.]
 
That's how the /O switch works. You probably need a different strategy. Scott's suggestion looks pretty good.

Code:
do file in source_dir\*
    set jpgname=%@filename[%file].jpg
    iff not exist dest_dir_1\%jpgname then
        copy %file dest_dir_1\%jpgname
        copy %file dest_dir_2\%jpgname
    endiff
enddo

[or something like that.]
Thanks Vince. Yes, I finally got that far in my reply to Scott (above), as a one-liner, but without the 'set' command. Would the one-liner (above) be improved by including the 'set' command, so that '%@filename[]' would only need to be used once, rather than multiple times as I had it?
 
Would the one-liner (above) be improved by including the 'set' command, so that '%@filename[]' would only need to be used once, rather than multiple times as I had it?
It might make it a little easier to read (and maybe microscopically faster). Why a one-liner ... alias? I find complicated aliases easier to code, understand, and maintain when the alias points to a BTM file.
 
Thanks both. I decided to go with Scott's suggestion, yielding more flexibility in displayed output:
Code:
copy /o C:\path1\* \\%NAS\path2\*.jpg > clip:
do asset in @clip:
  iff %@index[%asset,=>] GT 0 then
    copy /q %@word["=>",0,%asset] \\%NAS\path3\*.jpg
    echo %@word["=> ",1,%asset]
  elseiff %@index[%asset,copied] GT 0 then
    echo %asset
  endiff
enddo
If there are any new files in \path1\ which do not exist in \path2\, they are quietly copied to \path2\. Then, each one of that same group of new files is copied from \path1\ to \path3\, and the destination \path2\filenames are displayed. Finally, the the number of copied files (as output by the original copy command) is displayed, which is the desired result:

\\%NAS\path2\filename1
\\%NAS\path2\filename2
2 files copied

The reason for copying to \path3\ (on NAS) from \path1\ (on C:), rather than from \path2\ (on NAS) to \path3\ (on NAS), is that this way the files will only traverse the network once; if they were copied from \path2\ to \path3\ they would traverse the network twice (from NAS to local machine, then back to NAS).

Why does @word require quoting of the first parameter (separator characters), while @index does not require quoting of the second parameter (search string)?

Also, I fail to see the difference between @word and @field, since they by default both use the same group of separator characters. What is the definition of 'field' and 'word'?
 
Also, I fail to see the difference between @word and @field, since they by default both use the same group of separator characters. What is the definition of 'field' and 'word'?

Fields can be empty; words cannot.

Code:
v:\> echo %@fields["/",//foo//]
5

v:\> echo %@words["/",//foo//]
1

v:\> echo %@field["/",0,//foo//]
ECHO is OFF

v:\> echo %@word["/",0,//foo//]
foo

v:\> echo %@field["/",2,//foo//]
foo
 

Similar threads

Replies
7
Views
2K
Back
Top