为什么批处理文件中的命令 XCOPY 要求文件或文件夹?

我有一个简单的副本从-到脚本我的一个朋友谁丢失了一个文件离我的办公桌20公里。

当测试脚本时,系统会提示我的文件 shapes.atc是一个文件还是一个文件夹。

我可以告诉你,这是一个文件。我怎样才能自动复制它与我的朋友只需要双击批处理得到的文件复制工作完成。

xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\Shapes.atc
138834 次浏览
echo f | xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\Shapes.atc

实际上,xcopy 并不询问原始文件是否存在,而是希望将其放在名为 Shapees.atc 的新文件夹中,或者放在 Support 文件夹中(这正是您想要的)。

为了防止 xcopy 问这个问题,只需告诉他目标文件夹,这样就不会有歧义了:

xcopy /s/y "J:\Old path\Shapes.atc" "C:\Documents and Settings\his name\Support"

如果你想在目的地改变文件名,只需使用 copy (在复制文件时它比 xcopy 更适合) :

copy /y "J:\Old path\Shapes.atc" "C:\Documents and Settings\his name\Support\Shapes-new.atc

这个/i 开关可能是你之后要做的。

从 xcopy/?

/I 如果目的地不存在并复制多个文件, 假设目标必须是一个目录。

A seemingly undocumented trick is to put a * at the end of the destination - then xcopy will copy as a file, like so

xcopy c:\source\file.txt c:\destination\newfile.txt*

echo f | xcopy ...技巧不适用于本地化版本的 Windows,因为其提示符是不同的。

xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\*.*"

. . 应该这样做。

做一个好主意:

IF NOT EXIST "C:\Documents and Settings\His name\Application Data\Autodesk\AutoCAD 2010\R18.0\enu\Support\Shapes.atc" ECHO/ && ECHO/ && ECHO * * * * * COPY FAILED - Call JustME at 555-555-1212 && ECHO/ && pause

(假设您已经将以前的版本重命名为. old)

XCOPY  /Z  <----- restartable mode - good for large files.

虚拟父母的把戏

假设您的源文件和目标文件位于

%SRC_FILENAME% and %DST_FILENAME%

你可以使用两步法:

@REM on my win 7 system mkdir creates all parent directories also
mkdir "%DST_FILENAME%\.."
xcopy "%SRC_FILENAME% "%DST_FILENAME%\.."

这个问题可以解决

mkdir "c:\destination\b\c\file.txt\.."
@REM The special trick here is that mkdir can create the parent
@REM directory of a "virtual" directory (c:\destination\b\c\file.txt\) that
@REM doesn't even need to exist.
@REM So the directory "c:\destination\b\c" is created here.
@REM mkdir "c:\destination\b\c\dummystring\.." would have the same effect


xcopy "c:\source\b\c\file.txt" "c:\destination\b\c\file.txt\.."
@REM xcopy computes the real location of  "c:\destination\b\c\file.txt\.."
@REM which is the now existing directory "c:\destination\b\c"
@REM (the parent directory of the "virtual" directory c:\destination\b\c\file.txt\).

当我偶然发现一些非常狂野的东西时,我有了这个想法。./..- 从构建过程生成的命令行中构造。

附加“ *”的技巧可以在新扩展更短时发挥作用。您需要用空格填充新的扩展名,这只能通过用引号括起目标文件名来完成。例如:

xcopy foo.shtml "foo.html *"

这将在不提示的情况下复制和重命名。

“这不是一个错误,这是一个功能!”(我曾经在微软的停车场看到一辆挂着“功能”牌照的大众甲壳虫。)这些重命名的语义可以追溯到我写 DOS v. 1的时候。新名称中的字符会逐个取代旧名称中的字符,除非有通配符(?或 *)出现在新名称中。如果不向新名称添加空格,则从旧名称复制剩余字符。

The real trick is: Use a Backslash at the end of the target path where to copy the file. The /Y is for overwriting existing files, if you want no warnings.

Example:

xcopy /Y "C:\file\from\here.txt" "C:\file\to\here\"

对于 只有我提出的任务,最好的解决方案可能是根据 安迪 · 莫里斯不完整的建议执行以下命令:

xcopy "J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file\Shapes.atc" "C:\Documents and Settings\His name\Application Data\Autodesk\AutoCAD 2010\R18.0\enu\Support\" /Q /R /S /Y

This works for this simple file copying task because of

  • 只指定目标目录而不是目标文件,并且
  • ending destination directory with a backslash which is very important as otherwise XCOPY would even with /I prompt for file or directory on copying just a single file.

与该问题无关的其他参数包括:

  • /Q ... quiet
  • 是(操作系统语言独立)覆盖现有文件
  • 也覆盖只读,隐藏和系统文件
  • 从指定的目录和所有子目录。

我不知道这里是否真的需要 /S,因为目前还不清楚是只复制 J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file\Shapes.atc还是在 J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file的目录树中找到所有的 Shapes.atc

可以通过打开命令提示符窗口并在此窗口 xcopy /?中运行来读取参数的说明,以获得对 收到的帮助。


但是所提供的解决方案都不适用于文件复制任务,在这个任务中,单个文件应该被复制到与源文件相同的目录中,但是由于当前日期和时间在文件扩展名之前插入到文件名中,所以文件名不同。

源文件可以设置隐藏属性或系统属性,这些属性排除了 收到命令的使用。

用于创建时间戳文件的批处理文件也应该在 WindowsXP 上工作,该文件不包括 机器人复制,因为默认情况下在 WindowsXP 上不可用。

The batch file should work with any file including non typical files like .gitconfig or .htaccess which are files without a file extension starting with a point to hide them on *nix systems. Windows command processor interprets such files as files with no file name and having just a file extension because of the rule that everything after last point is the extension of the file and everything before last point is the file name.

For a complete task description and the final, fully commented solution see the post 创建文件的备份副本 in UltraEdit forum.

Patrick 的 Interociter Operator's查尔斯 B 的解决方案不起作用,因为如果目标文件不存在,使用 /Y并不能避免文件或目录提示符。

Andy Morris 的 格雷尼克斯的解决方案不能用于单文件复制任务,因为目标必须是目标文件的名称,而不是目标目录的名称。目标目录与源目录相同,但目标文件的名称与源文件的名称不同。

DosMan 的 政府的解决方案根本不适用于以一个点开始并且没有文件扩展名的文件。

例如,命令

xcopy C:\Temp\.gitconfig C:\Temp\.gitconfig_2016-03-07_15-30-00* /C /H /K /Q /R /V /Y

执行时出现以下错误消息:

中文: 无法展开第二个文件名以便与第一个匹配。
德语: 第二个数据名称不能扩展到第一个。

最后,Denis Ivin 的解决方案还有一个限制,即文件或目录提示的自动应答必须知道操作系统语言相关字符。

因此,我想到了一些方法,以便在英文 Windows 上获得 F,或者在德文 Windows 上获得 D,或者在... ... Windows 上获得 ?

And it is indeed possible to determine the language dependent character for an automatic answering of the prompt.

A hack is used to get the language dependent letter from prompt text without really copying any file.

命令 收到用于开始将批处理文件本身复制到临时文件的文件夹中,该文件扩展名为 TMP,用于目标文件。如果在临时文件文件夹中还没有具有该名称的文件,则 收到将提示该文件,这是不太可能的。

The handler of device NUL is used as an input handler for 收到 resulting in breaking the copying process after the prompt was output by 收到 two times.

This output is processed in a 为了 loop which is exited on first line starting with an opening parenthesis. This is the line on which second character defines the letter to use for specifying that destination is a file.

下面是一个批处理文件,使用 收到和代码来确定自动回答文件或目录提示所需的字母,从而在源文件的同一目录中创建一个有时间戳的单个文件副本,即使源文件是一个隐藏文件或系统文件,即使源文件以一个点开始并且没有文件扩展名。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Batch file must be started or called with name of a single file.


if "%~1" == "" exit /B
for /F "delims=*?" %%I in ("#%~1#") do if not "%%I" == "#%~1#" exit /B
if not exist "%~1" exit /B
if exist "%~1\" exit /B


rem Determine the character needed for answering prompt of
rem XCOPY for destination being a file and not a directory.


del /F "%TEMP%\%~n0.tmp" 2>nul
for /F %%I in ('%SystemRoot%\System32\xcopy.exe "%~f0" "%TEMP%\%~n0.tmp" ^<nul') do (
set "PromptAnswer=%%I"
setlocal EnableDelayedExpansion
if "!PromptAnswer:~0,1!" == "(" set "PromptAnswer=!PromptAnswer:~1,1!" & goto CopyFile
endlocal
)
echo ERROR: Failed to determine letter for answering prompt of XCOPY.
exit /B


:CopyFile
endlocal & set "PromptAnswer=%PromptAnswer%"
rem This is a workaround for files starting with a point and having no
rem file extension like many hidden files on *nix copied to Windows.


if "%~n1" == "" (
set "FileNameWithPath=%~dpx1"
set "FileExtension="
) else (
set "FileNameWithPath=%~dpn1"
set "FileExtension=%~x1"
)


rem Get local date and time in region and language independent format YYYYMMDDHHmmss
rem and reformat the local date and time to format YYYY-MM-DD_HH-mm-ss.


for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS get LocalDateTime /format:value') do set "LocalDateTime=%%I"
set "LocalDateTime=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%_%LocalDateTime:~8,2%-%LocalDateTime:~10,2%-%LocalDateTime:~12,2%"


rem Do the copy with showing what is copied and with printing success or
rem an error message if copying fails for example on sharing violation.


echo Copy "%~f1" to "%FileNameWithPath%_%LocalDateTime%%FileExtension%"


for /F %%I in ('echo %PromptAnswer% ^| %SystemRoot%\System32\xcopy.exe "%~f1" "%FileNameWithPath%_%LocalDateTime%%FileExtension%" /C /H /K /Q /R /V /Y') do set "FilesCopied=%%I"


if "%FilesCopied%" == "1" (echo Success) else echo ERROR: Copying failed, see error message above.

此批处理代码在德国 WindowsXPSP3x86和英国 Windows7SP1x64上进行了测试。

请参阅 UltraEdit 论坛上的文章 创建文件的备份副本,了解一个类似的、充分注释的批处理文件,解释批处理代码的所有部分。

为了理解所使用的命令及其工作原理,请打开一个命令提示窗口,在那里执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • del /?
  • echo /?
  • exit /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • wmic OS get /?
  • xcopy /?

此外,还应该阅读微软关于 使用命令重定向操作符的文章。

参考 XCopy Force File

对于强制文件,我们可以使用管道 "echo F |":

C:\Trash>xcopy 23.txt 24.txt
Does 24.txt specify a file name
or directory name on the target
(F = file, D = directory)?


C:\Trash>echo F | xcopy 23.txt 24.txt
Does 24.txt specify a file name
or directory name on the target
(F = file, D = directory)? F
C:23.txt
1 File(s) copied

为了强制使用文件夹,我们可以在 xcopy 中使用/i 参数,或者在目标文件夹的末尾使用反斜杠()。

我有完全相同的问题,其中是想要复制一个文件到外部硬盘驱动器备份的目的。 如果我想复制一个完整的文件夹,那么 COPY 很乐意创建目标文件夹并用所有文件填充它。 但是,我想每天复制一个文件,并将今天的日期添加到文件中。 COPY was happy to copy the file and rename it in the new format, but only as long as the destination folder already existed.

我的复制命令是这样的:

副本 C: SRCFOLDER MYFILE.doc D: DESTFOLDER MYFILE _ YYYYMMDD. doc

和您一样,我也四处寻找替代开关或其他复制类型的命令,但是没有一个能像我希望的那样工作。 Then I thought about splitting out the two different requirements by simply adding a make directory ( MD or MKDIR ) command before the copy command.

现在我知道了

D: DESTFOLDER

副本 C: SRCFOLDER MYFILE.doc D: DESTFOLDER MYFILE _ YYYYMMDD. doc

如果目标文件夹不存在,则创建它。 如果目标文件夹确实存在,那么它将生成一条错误消息。.但是,这并不能阻止批处理文件继续到 copy 命令。

错误消息显示: 子目录或文件 D: DESTFOLDER 已经存在

正如我所说的,错误消息并没有停止批处理文件的工作,这是一个非常简单的问题修复。

希望这能有所帮助。