Problem with file copying in Batch

82 views
Skip to first unread message

John Stockton

unread,
Nov 4, 2021, 6:30:13 PM11/4/21
to
In this code, the echo lines are merely for debugging

@echo FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
@echo TRYING : Xcopy /F %%J ZZZ\%%J
Xcopy /F %%J ZZZ\%%J
@echo.
)

That works, except that every time Xcopy is called, I get, on-screen,

"Does C:\MYSLIDES\ZZZ\33-xxxiii\11.jpg specify a file name
or directory name on the target
(F = file, D = directory)?"

An answer of F works, but I don't want to be asked; there may be over 100 calls. I've tried XCOPY /?, but cannot recognise a suitable option.

What should I do?

--
(c) John Stockton, near London, UK. Using Google Groups. |
Mail: J.R.""""""""@physics.org - or as Reply-To, if any. |

mokomoji

unread,
Nov 5, 2021, 7:52:48 AM11/5/21
to
z_sample.cmd - make test environment directory & file
----------------------------------------------------
@echo off
setlocal

cd /d "%~dp0"

set "z_mdpath=.\MYSLIDES\ZZZ\33-xxxiii"
set "z_rdpath=.\myslides\
rd /s /q "%z_rdpath%"
md "%z_mdpath%
echo %z_mdpath%\11.jpg>".\MYSLIDES\ZZZ\zzzz.txt"
echo %z_mdpath%\11.jpg>"%z_mdpath%\11.jpg"

endlocal
pause
------------------------------------------------------------

u'r cmd edit
------------------------------------------------------------
@echo off
setlocal
cd /d "%~dp0"

set "z_target=.\myslides\zzz"
set "z_forpath=.\myslides\zzz\zzzz.txt"

FOR /F "eol=; delims=" %%J IN (%z_forpath%) DO (
echo TRYING : Xcopy /F "%%~J" "%z_target%"
XCOPY /F "%%~J" "%z_target%\"
echo.
)

endlocal
pause

-------------------------------------------
u'r path
set "z_target=c:\myslides\zzz"
set "z_forpath=c:\myslides\zzz\zzzz.txt"

mokomoji

unread,
Nov 5, 2021, 7:58:03 AM11/5/21
to
z_sample.cmd

Precautions for use
Never use it as root.
Create a separate folder and create a test environment

All folders are deleted at runtime.

JJ

unread,
Nov 6, 2021, 8:46:34 AM11/6/21
to
On Thu, 4 Nov 2021 15:30:11 -0700 (PDT), John Stockton wrote:
> In this code, the echo lines are merely for debugging
>
> @echo FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
> FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
> @echo TRYING : Xcopy /F %%J ZZZ\%%J
> Xcopy /F %%J ZZZ\%%J
> @echo.
> )
>
> That works, except that every time Xcopy is called, I get, on-screen,
>
> "Does C:\MYSLIDES\ZZZ\33-xxxiii\11.jpg specify a file name
> or directory name on the target
> (F = file, D = directory)?"
>
> An answer of F works, but I don't want to be asked; there may be over 100 calls. I've tried XCOPY /?, but cannot recognise a suitable option.
>
> What should I do?

You're basically copying one file at a time based on a list of file names
with relative path. Use `copy /y` instead of using the XCOPY program. XCOPY
is intended for recursive copy.

John Stockton

unread,
Nov 7, 2021, 6:52:14 AM11/7/21
to
I did not understand Mokomoji - too many unnecessary alterations.

I copied that loop, with alteration, from an existing application using Xcopy /D/F /Y (Backup or Distribute, to a USB memory stick, for which I really wanted the Xcopy /D effect since generally most files will not need updating). In this case, the /D would be beneficial, but only slightly so. The list of
files will sometimes have duplicates. But this code will mostly run on a PC with C: being a SSD, so occasionally recopying a file over itself would not matter.

I could sort the list using SORT, and when copying put the name of the current file into an environment variable, and copy only if the next request was for a different name; but them I would not see the names on the screen in their "natural" order ...

Fx : test : but NO! XCOPY, unlike COPY, creates directories as needed.

I had not said that the files to be copied are *ALL* in subdirectories of \MYSLIDES, and there are currently 58 of those subdirectories have subdirectories of their own - e.g.

C:\MYSLIDES\01-I\22.JPG
C:\MYSLIDES\SCANS\PRESFRM1.PNG

C:\MYSLIDES\MONONEGS\06\X5Y7.JPG
C:\MYSLIDES\SCANS\OVEN\0102.PNG

I could use DIR /S /B /A:D to make a list for MKDIR to create all subdirectories that might be needed, but that is inelegant.

In the meanwhile, I'll try long runs of the script only when I have another use for the hand which is not busy typing F, e.g. by eating sandwiches with it.

Might ROBOCOPY be better?

John Stockton

unread,
Nov 7, 2021, 10:51:38 AM11/7/21
to
Sometimes, unexpectedly simple solutions exist :

prompt>type FFF.TXT | ZZZ-PICK camel barnes camel

in which FFF.TXT is a readily-constructed file of thousands of lines each containing a single letter F (finishing with a line not starting with F, and not using D).



But I have a further problem. I use MiniTrue to select the desired lines from the main text,
with -o meaning 'send the matching lines to Standard Output' -
pseudocode: MINITRUE -o XXX.HTM targets > ZZZ\ZZZZ.TXT
and it appears that, in a Windows 10 MS-DOS window and in Windows 10 Windows Terminal,
the redirection operation in this case fails to preserve the order of what it transmits
(here, that would be regrettable but not disastrous).
Perhaps MiniTrue needs an update. But possibly I can copy the original input file to ZZZ\ZZZZ.TXT
and then use -
pseudocode: MINITRUE ZZZ\ZZZZ.TXT lines-without-targets = "" ??

N.B. MiniTrue treats the 'targets' and a row of RegExps, so I can search for 'cow' without finding 'Moscow'.

The question is : what might I use instead of MiniTrue : AWK / GREP / SED /Another ?- I ask to be guided to read about the best one first - and where to get it from.

Briefly, I need to remove the lines I don't want from a file

mokomoji

unread,
Nov 7, 2021, 10:56:50 AM11/7/21
to
???????????????
I? Did I tell you to use a copy????
--------------------------------------------------------------------
JJ
You're basically copying one file at a time based on a list of file names
with relative path. Use `copy /y` instead of using the XCOPY program. XCOPY
is intended for recursive copy.
------------------------------------------------------------------
Isn't that what I said???

i only up-load source...
I added only source
??????????????????????????????

mokomoji

unread,
Nov 7, 2021, 11:03:44 AM11/7/21
to
Your problem is your business
up to what others have said, Am I responsible?
???????????????????????????????

mokomoji

unread,
Nov 7, 2021, 11:07:30 AM11/7/21
to
i put my hands up from this unlimited responsibility.

John Stockton

unread,
Nov 7, 2021, 12:02:48 PM11/7/21
to
On Sunday, 7 November 2021 at 15:51:38 UTC, John Stockton wrote:
> On Sunday, 7 November 2021 at 11:52:14 UTC, John Stockton wrote:
> > On Saturday, 6 November 2021 at 12:46:34 UTC, JJ wrote:
> > > On Thu, 4 Nov 2021 15:30:11 -0700 (PDT), John Stockton wrote:
>
> > In the meanwhile, I'll try long runs of the script only when I have another use for the hand which is not busy typing F, e.g. by eating sandwiches with it.
> Sometimes, unexpectedly simple solutions exist :
>
> prompt>type FFF.TXT | ZZZ-PICK camel barnes camel
>
> in which FFF.TXT is a readily-constructed file of thousands of lines each containing a single letter F (finishing with a line not starting with F, and not using D).

No - that runs, and shows the desired HTML; but it does not copy the files, because ZZZ\ZZZZ.TXT is empty (I don't know why)

LangerTom

unread,
Nov 7, 2021, 2:56:56 PM11/7/21
to




Am 04.11.2021 um 23:30 schrieb John Stockton:
> In this code, the echo lines are merely for debugging
>
> @echo FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
> FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
> @echo TRYING : Xcopy /F %%J ZZZ\%%J
> Xcopy /F %%J ZZZ\%%J
> @echo.
> )
>
> That works, except that every time Xcopy is called, I get, on-screen,
>
> "Does C:\MYSLIDES\ZZZ\33-xxxiii\11.jpg specify a file name
> or directory name on the target
> (F = file, D = directory)?"
>
> An answer of F works, but I don't want to be asked; there may be over 100 calls. I've tried XCOPY /?, but cannot recognise a suitable option.
>
> What should I do?
>


If I remember correctly you should add a trailing back slash to the
target. This tells xcopy to copy files to a target directory.

xcopy /f %%J ZZZ\%%J\

(not tested)

Thomas

John Stockton

unread,
Nov 11, 2021, 1:03:08 PM11/11/21
to
I think you have the right idea, but adjustment is needed.
A typical command line is
Xcopy /D /F /Y 37-xxxvii\20.jpg ZZZ\37-xxxvii\20.jpg
and I think I want to remove the trailing 20.jpg - but another typical line is
Xcopy /D /F /Y scans\oven\1516.png ZZZ\scans\oven\1516.png
with more sub-folders - I need to remove the characters after the LAST \ character.
The extension part will be three characters, but there could be any number of characters in the file name before the extension.

I don't know how to do that in reasonably brief pure batch.

Might %~pI be used? - seems not;
Xcopy /D /F /Y %%J ZZZ\%%~pJ copies to C:\MYSLIDES\ZZZ\MYSLIDES\37-XXXVII\20.JPG !!

I had thought, as I said, to automate typing all those F responses by piping in a file full of Fs - no good.

But it is possible to depress the F key when first asked for it, keep it down while all the XCOPY output scrolls rapidly upwards, and release it when a briskly-flowing line of Fs appears. Since this batch program will almost always be started by hand, and finishes directly after the copying, that is good enough. The repeat rate of the F key is much faster than that of my finger-pressing. If I release the F key too soon, F.BAT will maybe run (it starts File Explorer), but commands starting with multiple-F are not implemented here.



I have fixed the MiniTrue -o pipe/redirect error difficulty : I copy the input file, then in multiple MiniTrue passes on the copy, I : (0) prepend OMIT to all lines, (1 to N) alter OMIT to STET on lines wanted for various reasons, (N+1) remove the OMIT lines and the STET words. STET is logically redundant, but it helps when visually checking.

The line copy A+B+C A is not a good way to extend file A.

So : all is well enough with the image file copying, maybe.

It only remains to STET the <H#> lines and to remove, finally, all but the first of a set of consecutive such lines somehow.
And to adjust the dispositions of <ul> and/or <ol> in the source file.

LangerTom

unread,
Nov 11, 2021, 7:46:22 PM11/11/21
to
I hope that I have understood you correctly. If so the following snippet
shoud show you a solution for your problem. It works with 4 sub
routines, 3 of them used internally only, for an intermediate step to
process the name of the target directory. This routines use
call-by-reference method for returning results like PASCAL.

HTH Thomas

<code>


set "J=C:\MYSLIDES\33-xxxiii\11.jpg"
call :GetPathInfo "%J%" TargetPath
echo xopy /D /F /Y %J% %TargetPath%
REM xopy /D /F /Y %%J %TargetPath%

echo %SourcePath% %TargetPath%
pause
goto :eof


REM **** sub routines *****

:GetPathInfo
call :GetSourcePath "%~1" SourcePath
call :GetSourceDirname "%sourcePath%" DirName
call :GetTargetPAth TargetPath
goto :EOF


:GetSourcePath
Set "Oldpath=%cd%"
cd /d "%~1\.."
set "%~2=%cd%"
cd /d "%oldpath%
goto :EOF


:GetSourceDirName
Set "%2=%~n1"
goto :EOF


:GetTargetPath
Set "oldpath=%cd%"
cd /d "%SourcePath%\.."
Set "%~1=%cd%\ZZZ\%Dirname%\"
cd /d "%oldPath%"
goto :EOF




</code>

mokomoji

unread,
Nov 12, 2021, 1:46:01 PM11/12/21
to
z_sample.cmd
---------------------------------------------------------------------------------
@echo off

setlocal
cd /d "%~dp0"
echo "%~d0\"|find /i "%cd%" 2>nul>nul&&(
echo now folder root in not run~!
goto :end
)

set "z_mdpath.1=.\MYSLIDES\ZZZ\33-xxxiii"
set "z_mdpath.2=.\MYSLIDES\ZZZ\scans\oven"
set "z_rdpath=.\myslides\

rd /s /q "%z_rdpath%"
md "%z_mdpath.1%
md "%z_mdpath.2%

echo %z_mdpath.1%\11.jpg>".\MYSLIDES\ZZZ\zzzz.txt"
echo %z_mdpath.1%\20.jpg>>".\MYSLIDES\ZZZ\zzzz.txt"
echo %z_mdpath.2%\1516.jpg>>".\MYSLIDES\ZZZ\zzzz.txt"
echo %z_mdpath.1%\11.jpg>"%z_mdpath.1%\11.jpg"
echo %z_mdpath.1%\20.jpg>"%z_mdpath.1%\20.jpg"
echo %z_mdpath.2%\1516.jpg>"%z_mdpath.2%\1516.jpg"
:end
endlocal
pause
exit
----------------------------------------------------------------------------------------------

run.cmd
--------------------------------------------------------------------------------------
@echo off
setlocal
cd /d "%~dp0"

set "z_target=.\myslides\zzz"
set "z_forpath=%z_target%\zzzz.txt"
for /f "eol=; delims=" %%j in (%z_forpath%) do (

echo TRYING : xcopy /f "%%~j" "%%~dpj\%%~pj\"
xcopy /f "%%~j" "%z_target%\%%~pj\"
echo.
)
endlocal
pause
------------------------------------------------------------------------------------------------
godthem...


John Stockton

unread,
Nov 16, 2021, 6:44:25 PM11/16/21
to
On Friday, 12 November 2021 at 00:46:22 UTC, LangerTom wrote:

> I hope that I have understood you correctly. If so the following snippet
> shoud show you a solution for your problem. It works with 4 sub
> routines, 3 of them used internally only, for an intermediate step to
> process the name of the target directory. This routines use
> call-by-reference method for returning results like PASCAL.

The need is to truncate a filename immediately
before/after its final backslash.

Thank you for your efforts. Your code uses batch
language features which I know nothing about,
and I don't want to have code which I cannot read.

A year and a half ago, I wrote code calling JScript
from Batch to do string editing using RegExps; it
is in this newsgroup. I could not get it to what I need;
I think I know why - I need a RegExp containing
parentheses within a Batch FOR loop, and as then
written that defeated the parser.

So I tried with MiniTrue, hit the same situation,
but found a satisfactory work-round. The following
code is a bit voluble. TRANSFER.BAT can be constructed
by echoing the necessary lines before the loop which uses it.


@echo Starting TRANSFER.BAT %1 JRS 2021-11-16+
@echo %1 > Z-COPIER.BAT
@MTR -n -b- Z-COPIER.BAT (.*)(\\.*) = "set ZZZZZZ=\1"
@call Z-COPIER.BAT
@del Z-COPIER.BAT
@REM echo Xcopy /D /F /Y %1 ZZZ\%ZZZZZZ%\
Xcopy /D /F /Y %1 ZZZ\%ZZZZZZ%\
@echo.
@REM The End of TRANSFER.BAT

& in the main file, with ZZZZ.TXT being the list
of image filenames :


@FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO @(
call TRANSFER.BAT %%J
)

which I'm almost certain can be pruned, but not tonight.

The essential is to execute the code in TRANSFER.BAT
without it being lexically in the FOR loop.

From what you wrote, I think there must be a better way
of returning the result from MTR.

As is, I think the speed is (unimportantly) limited
by screen-writing time.

LangerTom

unread,
Nov 21, 2021, 3:13:50 AM11/21/21
to


Am 17.11.2021 um 00:44 schrieb John Stockton:
> On Friday, 12 November 2021 at 00:46:22 UTC, LangerTom wrote:
>
>> I hope that I have understood you correctly. If so the following snippet
>> shoud show you a solution for your problem. It works with 4 sub
>> routines, 3 of them used internally only, for an intermediate step to
>> process the name of the target directory. This routines use
>> call-by-reference method for returning results like PASCAL.
>
> The need is to truncate a filename immediately
> before/after its final backslash.
>
> Thank you for your efforts. Your code uses batch
> language features which I know nothing about,
> and I don't want to have code which I cannot read.
>

I found a solution for your problem, that ist very much simpler, smaller
and faster than my last suggestion.

Try:


FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO (
Xcopy /F %%J ZZZ\%%J\..\
)

This syntax addresses the path part only of your fully qualified
file name ZZZ\%%J and adds the trailing back space missing

.. is the representation of the parent part of a path and works on file
names in fully qualified file names too.

cd ..\.. will move upward two levels in a directory structure

HTH Thomas




John Stockton

unread,
Nov 21, 2021, 6:22:27 PM11/21/21
to
It has taken a genius to think of something which is
perfectly obvious in hindsight! It worked immediately;
but it put too much on the console, so I now have

@FOR /F "eol=; tokens=*" %%J IN (ZZZ\ZZZZ.TXT) DO @(
@echo copy MYSLIDES\%%J to MYSLIDES\ZZZ\%%J
@Xcopy %%J ZZZ\%%J\..\ > nul
)

which gives just the echoed line for each file copied.
It does give more if the apparent source file does not
exist; but that will not happen when I have completed
a recalcitrant piece of the preceding coding.

Thanks,

LangerTom

unread,
Nov 22, 2021, 4:47:47 PM11/22/21
to
You are welcome.
Reply all
Reply to author
Forward
0 new messages