BATCH文件要求文件或文件夹[重复]
Posted
技术标签:
【中文标题】BATCH文件要求文件或文件夹[重复]【英文标题】:BATCH file asks for file or folder [duplicate] 【发布时间】:2011-05-16 01:28:19 【问题描述】:我有一个简单的脚本副本,用于我们的一个人,他在离我办公桌 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
【问题讨论】:
使用管道命令 @aschipfl 这个问题在 ER 之前已经问过了,大约 5 年了。 @ultracrepidarian,我不得不承认我没有检查重复问题的年龄;幸运的是,没有关于那个的规则...... 【参考方案1】:一个看似没有记录的技巧是将*
放在目的地的末尾 - 然后xcopy
将复制为一个文件,就像这样
xcopy c:\source\file.txt c:\destination\newfile.txt*
echo f | xcopy ...
技巧不适用于提示不同的本地化版本的 Windows。
【讨论】:
当心使用 * 字符时可能会出现问题。我尝试使用建议的提示使用单个命令复制和重命名文件。源文件被命名为android.mk.armeabi.debug
。目标名称为Android.mk
。结果文件名是Android.mkbug
谢谢!我实际上遇到了一个错误,“无法扩展第二个文件名以便匹配第一个”,它只有 6 个 Google 点击(并且没有答案)。花了一段时间,但我想通了,它也解释了@user1222021 的观察。 源扩展名和目标扩展名要等长。如果目标扩展名短,eg.shtml
到.html*
,目标将“获得”字母,就好像放在源扩展之上一样,eg .htmll
。如果目标扩展longer,则会出现上述错误。
这种“延迟”效应强烈表明开发人员根据源扩展的长度分配了一个缓冲区,然后重用该缓冲区来存储目标扩展的长度,而不用空终止 C 字符串。据推测,开发人员假设没有人会更改正在复制的文件的扩展名,可能是因为 那时(xcopy 于 1985 年首次发布,尽管我确信它已经被重写),它使用备用扩展名来指示文件的变体几乎没有现在(如果它已知的话)那么流行。那时的人们只是使用不同的文件名。
这也适用于重命名我的文件 FYI xcopy Hello.txt test2\Hello2.txt*
有没有办法始终复制为目录?【参考方案2】:
实际上xcopy不会问你原始文件是否存在,而是你是否想把它放在一个名为Shapes.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
【讨论】:
+1 表示copy
而不是 xcopy
建议 :)
当然,copy
不会创建路径,如果它不存在的话。
而copy
不会打印出它在做什么(又名cp -v
)。
如果您将目标指定为目录,则可以添加尾部反斜杠 - 如果目录不存在,这可以防止出现问题。 (文件名保持不变)
谢谢,我花了 20 多分钟才弄清楚这么简单的事情,不需要创建新文件夹,令我惊讶的是 xcopy 只是不容易自动复制、重命名和覆盖文件【参考方案3】:
真正的诀窍是:在复制文件的目标路径末尾使用反斜杠。 /Y 用于覆盖现有文件,如果您不想要任何警告。
示例:
xcopy /Y "C:\file\from\here.txt" "C:\file\to\here\"
【讨论】:
这对我来说效果很好。谢谢【参考方案4】: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
【讨论】:
我有一个类似的问题,涉及 .zip 文件而不是 .atc,这是此处发布的 3 个实际有效的答案。 此解决方案可能不适用于某些 Windows 本地化。或者,您可以将星号附加到目标文件名,并且 xcopy 不会询问任何内容。这里有更多细节:***.com/a/14022309/532647. 虽然这会破坏本地化,但它是使用管道的一个很好的例子。【参考方案5】:引用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 参数或在目标文件夹的末尾使用反斜杠()。
【讨论】:
这正是我在 Visual Studio 项目构建设置中设置后期作业时想要的。 请注意存在本地化问题 - 它适用于英语 Windows 版本,但例如在德语 Windows 上它将是“d = file (datei), v = directory (verzeichnis)” ,所以你应该写echo d | xcopy 23.txt 24.txt
。【参考方案6】:
/i 开关可能是您所追求的。
来自 xcopy /?
/I 如果目标不存在并且复制多个文件, 假定目的地必须是一个目录。
【讨论】:
这个标志的作用与 OP 所追求的相反:它告诉 xcopy 假定一个目录,而不是假定一个文件。【参考方案7】:好吧,对于just me 提出的任务,根据Andy Morris 的不完整建议,也许最好的解决方案是以下命令:
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
这适用于这个简单的文件复制任务,因为
仅指定目标目录而不是目标文件和 用反斜杠结束目标目录,这一点非常重要,否则 XCOPY 甚至会在/I
提示输入文件或目录时仅复制一个文件。
与问题无关的其他参数有:
/Q
... 安静
/Y
... 是(与操作系统语言无关)覆盖现有文件
/R
... 也覆盖只读、隐藏和系统文件
/S
...来自指定目录和所有子目录。
好吧,我不知道这里是否真的需要/S
,因为目前还不清楚是应该复制J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file\Shapes.atc
,还是应该在J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file
的目录树中的任何位置找到所有Shapes.atc
。
可以通过打开命令提示符窗口并在此窗口中运行xcopy /?
来阅读参数说明,以获取XCOPY 的帮助输出。
但所提供的解决方案均不适用于文件复制任务,在该任务中,应将单个文件复制到与源文件相同的目录中,但由于当前日期和时间在文件扩展名之前的文件名中插入了不同的文件名,因此文件名不同.
源文件可以设置隐藏或系统属性,不包括 COPY 命令的使用。
用于创建时间戳文件的批处理文件应该也可以在不包括 ROBOCOPY 的 Windows XP 上工作,因为默认情况下在 Windows XP 上不可用。
批处理文件应该适用于任何文件,包括非典型文件,如.gitconfig
或.htaccess
,这些文件没有文件扩展名,以在 *nix 系统上隐藏它们的点开头。 Windows 命令处理器将此类文件解释为没有文件名且只有文件扩展名的文件,因为最后一点之后的所有内容都是文件的扩展名,最后一点之前的所有内容都是文件名。
有关完整的任务描述和最终的完整评论解决方案,请参阅 UltraEdit 论坛中的帖子Create a backup copy of files。
Patrick's、Tirtha R's、Interociter Operator's 和 CharlesB's 解决方案不起作用,因为如果目标文件不存在,使用 /Y
不会避免文件或目录提示。
Andy Morris' 和grenix's 解决方案不能用于单个文件复制任务,因为destination 必须是目标文件的名称,而不是目标目录的名称。目标目录与源目录相同,但目标文件名与源文件名不同。
DosMan's 和 Govert's 解决方案根本不适用于以点开头且没有文件扩展名的文件。
例如命令
xcopy C:\Temp\.gitconfig C:\Temp\.gitconfig_2016-03-07_15-30-00* /C /H /K /Q /R /V /Y
执行时会出现以下错误消息:
英文:无法扩展第二个文件名以匹配第一个。 德语:Zweiter Dateiname konnte nicht so erweitert werden, dass er zum ersten passt。
最后Denis Ivin's 解决方案的限制是必须知道用于自动回答文件或目录提示的操作系统语言相关字符。
所以我想到了在英语 Windows 上为 File 获取 F
或在德语 Windows 上为 Datei 获取 D
或为 ... on 获取 ?
的方法... Windows 自动。
确实有可能确定自动回答提示的语言相关字符。
黑客用于从提示文本中获取与语言相关的字母,而无需真正复制任何文件。
命令 XCOPY 用于开始将批处理文件本身复制到临时文件的文件夹中,文件扩展名为目标文件的 TMP。如果临时文件夹中还没有具有该名称的文件,这将导致 XCOPY 提示,这不太可能。
设备 NUL 的处理程序用作 XCOPY 的输入处理程序,导致 XCOPY 输出提示后中断复制过程两次。
此输出在 FOR 循环中处理,该循环在第一行以左括号开始退出。这是第二个字符定义用于指定目标是文件的字母的行。
这是一个批处理文件,它使用 XCOPY 代码来确定自动回答文件或目录提示所需的字母,从而在与源文件,即使源文件是隐藏文件或系统文件,即使源文件以点开头且没有文件扩展名。
@echo off
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
setlocal EnableDelayedExpansion
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"
if "!PromptAnswer:~0,1!" == "(" (
set "PromptAnswer=!PromptAnswer:~1,1!"
goto CopyFile
)
)
echo ERROR: Failed to determine letter for answering prompt of XCOPY.
exit /B
:CopyFile
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.
)
此批处理代码已在德语 Windows XP SP3 x86 和英语 Windows 7 SP1 x64 上测试。
请参阅 UltraEdit 论坛中的 Create a backup copy of files 帖子以获取类似的、完整注释的批处理文件,该文件解释了批处理代码的所有部分。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
del /?
echo /?
exit /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
wmic OS get /?
xcopy /?
还应阅读有关 Using command redirection operators 的 Microsoft 文章。
【讨论】:
【参考方案8】:附加“*”的技巧可以在新扩展名较短时起作用。您需要用空格填充新扩展名,这只能通过将目标文件名括在引号中来完成。例如:
xcopy foo.shtml "foo.html *"
这将在没有提示的情况下复制和重命名。
“这不是错误,而是功能!” (我曾经在微软停车场看到一辆大众甲壳虫,上面印着“FEATURE”的名牌。)这些重命名语义可以追溯到我写 DOS v.1 的时候。新名称中的字符将一一替换旧名称中的字符,除非新名称中出现通配符(? 或 *)。如果不向新名称添加空格,则会从旧名称中复制剩余的字符。
【讨论】:
【参考方案9】: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.
【讨论】:
【参考方案10】:虚拟父母把戏
假设你有你的源文件和目标文件
%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\).
当我在构建过程生成的命令行中偶然发现一些非常疯狂的 ../..-constructs 时,我产生了这个想法。
【讨论】:
【参考方案11】:我遇到了完全相同的问题,想将文件复制到外部硬盘驱动器以进行备份。 如果我想复制一个完整的文件夹,那么 COPY 很乐意创建目标文件夹并用所有文件填充它。 但是,我想每天复制一次文件并将今天的日期添加到文件中。 COPY 很乐意复制文件并将其重命名为新格式,但前提是目标文件夹已经存在。
我的复制命令如下所示:
复制 C:\SRCFOLDER\MYFILE.doc D:\DESTFOLDER\MYFILE_YYYYMMDD.doc
和你一样,我四处寻找替代开关或其他复制类型命令,但没有什么能像我想要的那样奏效。 然后我想通过在复制命令之前简单地添加一个 make 目录( MD 或 MKDIR )命令来拆分这两个不同的要求。
所以现在我有
MKDIR D:\DESTFOLDER
复制 C:\SRCFOLDER\MYFILE.doc D:\DESTFOLDER\MYFILE_YYYYMMDD.doc
如果目标文件夹不存在,则创建它。 如果目标文件夹确实存在,那么它会生成一条错误消息。但是,这不会阻止批处理文件继续执行复制命令。
错误消息说: 子目录或文件 D:\DESTFOLDER 已存在
正如我所说,错误消息不会停止批处理文件的工作,它是解决问题的一个非常简单的方法。
希望这会有所帮助。
【讨论】:
以上是关于BATCH文件要求文件或文件夹[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Spring Batch中如何读取多个CSV文件合并数据进行处理?
从 CSV/TXT 创建文件夹并将匹配列移动到 Powershell 或 Batch 中的新目录