我是一个创建批处理文件的新手,我希望有人可以帮助我。我们的一名工作人员通过电子邮件收到压缩的pdf文档,然后将其复制到桌面上的文件夹中。在该文件夹中,我希望她能够运行
的批处理脚本一个。将压缩的内容解压缩到网络目录,即\ server \ contracts 在此目录下,进程将为每组合同创建文件夹,即\ server \ contracts \ Masterson(其名称与压缩文件名相同)。
B中。然后,批处理过程应根据文件名将选定的几个pdf文档复制到网络目录中。每个文件都包含一个数字,它将按以下方式进行:Masterson + 1.pdf>> \ server \ contracts \ Item1和\ server \ contracts \ Item2等.Masterson + 1.pdf将进入\ server \ contracts \ Item1而没有文件夹名称,Paisley + 1 certificate.pdf和Johnsonville + 1 document.pdf 。
问题是公司没有按照说明操作,编号可以在文件名的开头,中间或末尾。此外,遗憾的是,压缩文件和pdf文档的名称中还有空格。目前,我们只将4个文件名复制到单独的目录中供其他人查看和验证。
以下是我到目前为止看到的网站:
@Echo off
SETLOCAL
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in
("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
::The Output Folders
set "Output1=\\server\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\server\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
set "Output8a=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8b=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "usebackq delims=|" %%a in ('dir /b /s %InputFolder%\%extensions%
2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
set "Fichier=%%a"
echo Treating _^> %%a
if "!Fichier:~0,-2!"==" 1" COPY "%%~a" %Output1%
if "!Fichier:~0,-2!"==" 6" COPY "%InputFolder%\~%%a" %Output6%
if "!Fichier:~0,-3!"=="8A" COPY "%InputFolder%\%%a" %Output8A%
if "!Fichier:~0,-3!"=="8B" COPY "%InputFolder%\%%a" %Output8B%
if "!Fichier:~0,-3!"=="8a" COPY "%InputFolder%\%%a" %Output8a%
if "!Fichier:~0,-3!"=="8b" COPY "%InputFolder%\%%a" %Output8b%
::Waiting ~5 seconds
ping localhost -n 6 >nul
)
::Return to the loop
goto:Loop
当然这不起作用。请帮忙!
答案 0 :(得分:0)
嗯 - 勇敢的尝试!如此接近......
让我们来看第一部分
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
这里的错误是delims
子句仅在for /f
中可用。 for /r
始终将整个文件名传递给元变量%%I
。
在我的系统上我使用%server%\u
进行测试 - u
是分配给U:\
上server
的服务器上的共享资源。< / p>
for /R "\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION" %%I IN ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
为我愉快地工作 - 将提取的文件提供给&#34; u:\ contracts \ RECEIVED 2017-18 APPLICATION&#34;
代码的第二部分是检查&#34; C:\ Users \ eartha.kitt \ Desktop \ Test&#34;不是&#34; \%server%\ u \ contracts \ RECEIVED 2017-18 APPLICATION&#34; - 非常合理地分配给变量名以便于调整。
这是我修改过的代码:
SET "terminatefilename=stop.txt"
DEL "%terminatefilename%" 2>nul
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
set "InputFolder=\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION"
::The Output Folders
set "Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\%server%\u\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\%server%\u\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\%server%\u\contracts\ITEM 8B 16-17 REVISED CALENDARS"
FOR /f "tokens=1*delims==" %%b IN ('set output') DO MD "%%c" 2>nul
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "delims=|" %%a in ('dir /b /s "%InputFolder%\%extensions%" 2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
SET "copied="
echo Treating _^> %%a
REM OPTION 1 - Key string must be at end-of name part
set "Fichier=%%~Na"
if /i "!Fichier:~0,-2!"==" 1" COPY "%%a" "%Output1%"&SET "copied=Y"
if /i "!Fichier:~0,-2!"==" 6" COPY "%%a" "%Output6%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8A" COPY "%%a" "%Output8A%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8B" COPY "%%a" "%Output8B%"&SET "copied=Y"
REM OPTION 2 - Key string may be anywhere in filename
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8B" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8B%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8A" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8A%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 6" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output6%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 1" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output1%"&SET "copied=Y"
)
)
::Waiting ~5 seconds
timeout 6 >NUL
:: Test for exit
IF EXIST "%terminatefilename%" DEL "%terminatefilename%"&GOTO :EOF
::Return to the loop
goto:Loop
首先,我设置terminatefilename
,以便创建此文件将终止批处理(它在代码中设计为无限循环)
接下来,我覆盖了您的inputfolder
名称以适合我的系统。
然后是输出目录。我调整了他们的名字以适合我的系统。请注意,批处理在很大程度上不区分大小写,因此设置Output8A
和Output8a
会设置相同的变量。批处理命令区分大小写的唯一时间是for
语句中的元变量(循环控制变量)。
然后我插入一行来创建目标目录。这使用set
命令列出以output
格式开始Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS
的变量(其中server
将被解析)。该命令读取set
命令的输出,使用=
作为分隔符,并将output1
分配给%%b
,将\\%server%\u\contracts\ITEM 1 17-18 CERTS
分配给%%c
。我们希望确保目录%%c
存在,因此我们使用md
命令进行操作,并忽略2>nul
已存在的投诉。
接下来是for/f
。 for /f
读取(thisfilename)
或("this literal value")
或('the output of this command')
的每一行,但是当您需要从名称必须双引号的文件中读取时beacuse包含空格,那么语法为for /f "usebackq"...
(idontknow)
或("this filename containing spaces")
或('ive no idea whatever')
或(“此命令的输出”)
所以没有必要使用usebackq
- 事实上,它会适得其反。
delims=|
是可选的,可以由delims=
替换,因为dir
命令的输出永远不会包含|
(在文件或目录名中是非法的)。您执行需要delims
子句,因为默认分隔符包含 Space ,默认tokens
为1
所以只有第一个直到第一个空格的每行输出的字符串将被分配给%%a
。
嗯 - 你rem
中了for/r
。遗憾的是,for /r
中的目标目录不能成为元变量。
接下来,我已经清除了一个copied
标记&#34;到目前为止,此文件尚未被复制&#34;
接下来,将fichier
设置为仅文件名的名称部分。由于您使用.pdf
作为过滤器,因此for/f
输出的每个名称都是完整文件名,以.pdf
接下来,使用if
语句电池几乎正确。 /i
使比较不区分大小写,以便它可以处理8a
和8A
。 ==
两侧的字符串必须相同才能通过==
测试,因此在8
测试中需要一个3个字符的字符串。< / p>
您显然正在尝试使用copy
命令并尝试使用适当的字符串来提供它。 %%~a
剥离任何封闭引号的%%a
。 %%a
没有包含引号 - 只是整个文件名,所以在这个实例中什么都不做。 %InputFolder%\~%%a
汇总来自InputFolder
,&#34; \〜&#34;的值和%%a
- 表示&#34;%inputfolder%\〜%inputfolder%\ filenameandextension of %% a &#34;。最后两个将被解析为相同,禁止~
。
由于整个文件名包含在%%a
中,因此源文件所需的所有内容都是"%%a"
- 引用它,因为它可能包含空格。
嗯 - 目标目录(我们已经使用for /f...%%b
建立了它)也可以包含空格,因此也需要引用它。
如果该行生效,我会将标记copied
设置为Y
。实际上,它可以设置为任何非空值,因为整个对象是用if defined
语句来解释它是否存在以绕过后来复制同一文件的任何尝试(请记住 - copied
为每个文件清除)
现在 - 第二个选项。这实际上是比子串版本更强大的所需目标字符串检测器,并将检测文件名中任何位置的目标字符串。
如果echo
%%~na
只将文件findstr
的名称部分findstr
添加到/L
,请设置为/i
以查找c:"some literal string"
文字字符串>nul
不区分大小写findstr
并输出与无处的errorlevel
),然后0
会将1
设置为{{} 1}}如果找到,则/L
。 (If errorlevel n
在这里是多余的,我习惯性地使用它来提醒我使用文字字符串,而不是正则表达式)
errorlevel
当前为n
或大于n
,则 copied
为真,因此如果找到该字符串,我们会复制并设置{{1}以前的标志。
我颠倒了测试的顺序,因为我使用我使用的编辑器更容易。
现在 - 这种做法存在不利因素。这是一把双刃剑。由于检测到目标字符串它出现在文件名中,whatever whatever 10 something something.pdf
将通过1
的测试,因为 Space 1出现在其名称中。
当循环结束时,使用timeout
等待,将输出重定向到nul
以使其管道向下。请注意,您的延迟在for
循环内 - 所以它在处理完每个文件后等待6秒,而不是在处理整个批次后6秒。
最后,如果您从其他terminatefilename
实例创建cmd
,批处理将会干净地退出并为您杀死terminatefilename
。比control-c更清洁。
最后一点:由于你是copy
文件,而不是MOVE
它,它可能仍然存在于同一个地方,大概是在6秒过后,将被无休止地复制和重新复制。您可能需要进行调整才能达到预期效果。