无忧启动论坛

标题: 这段批处理,如何书写才能更精练些? [打印本页]

作者: 青青草    时间: 2017-2-15 14:48
标题: 这段批处理,如何书写才能更精练些?
本帖最后由 青青草 于 2017-2-18 12:46 编辑

下面这段批处理,如何书写才能更精练些?
if exist PE\10PEX64\WXPE\10PEX64.wim (xcopy /s/e/i/y PE\10PEX64 %name%:\)
if exist PE\8.1PEX64\WXPE\8.1PEX64.wim (xcopy /s/e/i/y PE\8.1PEX64 %name%:\)
if exist PE\8PEX64\WXPE\8PEX64.wim (xcopy /s/e/i/y PE\8PEX64 %name%:\)
if exist PE\7PEX64\WXPE\7PEX64.wim (xcopy /s/e/i/y PE\7PEX64 %name%:\)

if exist PE\10PEX86\WXPE\10PEX86.wim (xcopy /s/e/i/y PE\10PEX86 %name%:\)
if exist PE\8.1PEX86\WXPE\8.1PEX86.wim (xcopy /s/e/i/y PE\8.1PEX86 %name%:\)
if exist PE\8PEX86\WXPE\8PEX86.wim (xcopy /s/e/i/y PE\8PEX86 %name%:\)
if exist PE\7PEX86\WXPE\7PEX86.wim (xcopy /s/e/i/y PE\7PEX86 %name%:\)

if exist PE\WIN03PE\WXPE\WIN03PE.wim (xcopy /s/e/i/y PE\WIN03PE %name%:\)

请高手们赐教!谢谢了!

综合几位大神结果:

for %%a in (X64 X86) do (
    for %%v in (10 8.1 8 7) do call :_FUNC %%v PE%%a
)
call :mycopy "WIN03PE"
exit 0

:_FUNC
set ver_arch=%1%2
call :mycopy "%ver_arch%"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)

:done

感觉:还是直接这样好:


for %%a in (64 86) do (
    for %%v in (10 8.1 8 7) do call :_FUNC %%vPEX%%a
)
exit 0

:_FUNC
set ver_arch=%1%2
if exist PE\%ver_arch%\WXPE\%ver_arch%.wim (xcopy /s/e/i/y PE\%ver_arch% %name%:\)

这种方法也很好:

for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 8PEX64 8PEX86 7PEX64 7PEX86 WIN03PE) do if exist "%~dp0\PE\%%a\WXPE\%%a.wim" xcopy "%~dp0\PE\%%a" "%name%:" /s /e /i /y

最后定稿:
for /r PE %%d in (*.WIM) do xcopy PE\%%~nd %name%: /s /e /i /y

解决问题的方法,多种多样,多姿多彩,让人开了眼界。

一题多解,既扩大了思维,又增长了知识!非常好!

感谢大神们!


作者: 虫子樱桃    时间: 2017-2-15 16:04
好像要用for,遍历数组。批处理不懂,哈哈
作者: pseudo    时间: 2017-2-15 16:54
本帖最后由 pseudo 于 2017-2-15 16:56 编辑

用for显得复杂费解,这样清晰些:
call mycopy "10PEX64"
call mycopy "8.1PEX64"
call mycopy "8PEX64"
call mycopy "7PEX64"

call mycopy "10PEX86"
call mycopy "8.1PEX86"
call mycopy "8PEX86"
call mycopy "7PEX86"

call mycopy "WIN03PE"
goto :done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
exit
:done

这里双引号可以考虑去掉,相应%~1写成%1。带双引号更保险。
作者: 古今一梦    时间: 2017-2-15 18:14
for %%i in (10PEX86 8.1PEX86) do if exist \PE\%%i\WXPE\%%i.wim xcopy /s/e/i/y PE\%%i  %name%:\

摸一下鱼哈
作者: 青青草    时间: 2017-2-15 20:46
pseudo 发表于 2017-2-15 16:54
用for显得复杂费解,这样清晰些:
call mycopy "10PEX64"
call mycopy "8.1PEX64"

谢谢大神!
试了,不行。WXPE文件夹中,没有文件。
作者: 青青草    时间: 2017-2-15 21:09
pseudo 发表于 2017-2-15 16:54
用for显得复杂费解,这样清晰些:
call mycopy "10PEX64"
call mycopy "8.1PEX64"

call mycopy "10PEX64"
call mycopy "8.1PEX64"
call mycopy "8PEX64"
call mycopy "7PEX64"

call mycopy "10PEX86"
call mycopy "8.1PEX86"
call mycopy "8PEX86"
call mycopy "7PEX86"

call mycopy "WIN03PE"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
exit
:done

感觉没错呀,怎么就不可以呢?奇怪了!
作者: 古今一梦    时间: 2017-2-15 21:30
call :mycopy "10PEX64"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
:done
exit
应该是这样吧


作者: slore    时间: 2017-2-15 21:45
  1. @echo off
  2. for %%a in (X64 X86) do (
  3.     for %%v in (10 8.1 8 7) do call :_FUNC %%v %%a
  4. )
  5. pause
  6. exit 0

  7. :_FUNC
  8. set ver_arch=%1%2
  9. echo PE\%ver_arch%PE\WXPE\%ver_arch%.wim
复制代码

作者: 青青草    时间: 2017-2-15 23:16
pseudo 发表于 2017-2-15 16:54
用for显得复杂费解,这样清晰些:
call mycopy "10PEX64"
call mycopy "8.1PEX64"

综合几位大神结果:
call :mycopy "WIN03PE"
for %%a in (X64 X86) do (
    for %%v in (10PE 8.1PE 8PE 7PE) do call :_FUNC %%v %%a
)
exit 0

:_FUNC
set ver_arch=%1%2
call :mycopy "%ver_arch%"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
:done

再次谢谢大神!
作者: 青青草    时间: 2017-2-15 23:17
古今一梦 发表于 2017-2-15 21:30
call :mycopy "10PEX64"
goto done

综合几位大神结果:
call :mycopy "WIN03PE"
for %%a in (X64 X86) do (
    for %%v in (10PE 8.1PE 8PE 7PE) do call :_FUNC %%v %%a
)
exit 0

:_FUNC
set ver_arch=%1%2
call :mycopy "%ver_arch%"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
:done

谢谢大神!
作者: 青青草    时间: 2017-2-15 23:18
slore 发表于 2017-2-15 21:45

综合几位大神结果:
call :mycopy "WIN03PE"
for %%a in (X64 X86) do (
    for %%v in (10PE 8.1PE 8PE 7PE) do call :_FUNC %%v %%a
)
exit 0

:_FUNC
set ver_arch=%1%2
call :mycopy "%ver_arch%"
goto done

:mycopy
if exist PE\%~1\WXPE\%~1.wim (xcopy /s/e/i/y PE\%~1 %name%:\)
:done

谢谢大神!
作者: 青青草    时间: 2017-2-16 11:49
本帖最后由 青青草 于 2017-2-16 13:43 编辑

感觉:还是直接这样好:

for %%a in (64 86) do (
for %%v in (10 8.1 8 7) do call :_FUNC %%vPEX%%a
)
exit 0

:_FUNC
set ver_arch=%1%2
if exist PE\%ver_arch%\WXPE\%ver_arch%.wim (xcopy /s/e/i/y PE\%ver_arch% %name%:\)

作者: nttwqz    时间: 2017-2-16 13:22
个人还是觉得4楼for命令比较简单,明明一句的事儿,不知道为何非要一堆代码来完成,而且这一堆代码也没觉得比一句for强多少,看着更复杂了……
作者: 青青草    时间: 2017-2-16 13:53
本帖最后由 青青草 于 2017-2-17 00:18 编辑
nttwqz 发表于 2017-2-16 13:22
个人还是觉得4楼for命令比较简单,明明一句的事儿,不知道为何非要一堆代码来完成,而且这一堆代码也没觉得 ...


可能是语句“if exist PE\%%i\WXPE\%%i.wim xcopy /s/e/i/y PE\%%i  %name%:\”的原因吧,
试了,不行。

作者: nttwqz    时间: 2017-2-16 20:34
我相信for绝对可以做到这种事情,具体哪里不行可以echo on然后分析原因,再具体解决。

以下代码经过实机测试可行!

  1. @echo off
  2. rem 自动请求以管理员权限运行
  3. reg query HKU\S-1-5-20>nul 2>nul || echo CreateObject^("Shell.Application"^).ShellExecute "%~f0", "", "", "runas", 1 > "%temp%\getadmin.vbs" && cscript //b "%temp%\getadmin.vbs" && exit /b & del "%temp%\getadmin.vbs" /f /q>nul 2>nul
  4. set name=c
  5. ::for方法一
  6. for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 7PEX64 7PEX86) do if exist "%~dp0\PE\%%a\WXPE\%%a.wim" xcopy "%~dp0\PE\%%a" "%name%:" /s /e /i /y

  7. ::for方法二
  8. for /f %%b in ('echo 10PEX64 ^& echo 10PEX86 ^& echo 8.1PEX64 ^& echo 8.1PEX86 ^& echo 7PEX64 ^& echo 7PEX86') do if exist "%~dp0\PE\%%b\WXPE\%%b.wim" xcopy "%~dp0\PE\%%b" "%name%:" /s /e /i /y

  9. pause & exit
复制代码

作者: slore    时间: 2017-2-16 22:04
nttwqz 发表于 2017-2-16 20:34
我相信for绝对可以做到这种事情,具体哪里不行可以echo on然后分析原因,再具体解决。

以下代码经过实机 ...

不是一味的行数少就好。

看例子让楼主知道for的嵌套,还有"函数"的使用的方法。
以后处理会更灵活。

比如:

X86\PE\WXPE\8.1PEX86.wim
X64\PE\WXPE\8.1PEX64.wim

你这种一行就不行了,也就是适合楼主1楼的例子。
作者: nttwqz    时间: 2017-2-16 23:05
slore 发表于 2017-2-16 22:04
不是一味的行数少就好。

看例子让楼主知道for的嵌套,还有"函数"的使用的方法。

这个同样可以一行,不过用到for嵌套是真的。当然,你可以写成两行或更多行

  1. for %%c in (X86 X64) do for %%d in (10PE%%c 8.1PE%%c 7PE%%c) do if exist "%~dp0\%%c\PE\%%d\WXPE\%%d.wim" xcopy "%~dp0\%%c\PE\%%d" "%name%:" /s /e /i /y
复制代码


我觉得吧,楼主提的问题并不复杂,能简单解决就不用复杂的方法,除非有必要,呃~这么说好像歧义挺大的……

从楼主提这个问题来看,楼主似乎对for应用还不是很熟练,以个人以往学习for的经历来看,for嵌套,多重for嵌套远比一个for来的更复杂,更难以理解,还是先掌握一个for来的更合适,当然,也有不少人可能理解的很快。

总之这,多了解点东西总是好的。
作者: 青青草    时间: 2017-2-17 00:28
nttwqz 发表于 2017-2-16 23:05
这个同样可以一行,不过用到for嵌套是真的。当然,你可以写成两行或更多行

这样的讨论,我个人感觉非常好!解决问题的方法多种多样,让人大开眼界,从中学习了好多知识!
谢谢大神!
作者: 青青草    时间: 2017-2-17 00:28
slore 发表于 2017-2-16 22:04
不是一味的行数少就好。

看例子让楼主知道for的嵌套,还有"函数"的使用的方法。

这样的讨论,我个人感觉非常好!解决问题的方法多种多样,让人大开眼界,从中学习了好多知识!
谢谢大神!
作者: 青青草    时间: 2017-2-17 11:28
本帖最后由 青青草 于 2017-2-17 12:41 编辑
nttwqz 发表于 2017-2-16 20:34
我相信for绝对可以做到这种事情,具体哪里不行可以echo on然后分析原因,再具体解决。

以下代码经过实机 ...


请教大神一下:
在批处理当前目录下
for %%a in (i386-pc i386-efi x86_64-efi locale fonts) do md out\boot\grub\%%a
这样可以。
同样在批处理当前目录下
for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 7PEX64 7PEX86) do if exist "PE\%%a\WXPE\%%a.wim" xcopy "PE\%%a" "%name%:" /s /e /i /y
这样就不可以。
for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 7PEX64 7PEX86) do if exist "%~dp0\PE\%%a\WXPE\%%a.wim" xcopy "%~dp0\PE\%%a" "%name%:" /s /e /i /y
可以。
在这里,为什么非要加上“当前批处理文件所在完整目录”不可?!

我真被搞糊涂了!


作者: nttwqz    时间: 2017-2-17 17:58
青青草 发表于 2017-2-17 11:28
请教大神一下:
在批处理当前目录下
for %%a in (i386-pc i386-efi x86_64-efi locale fonts) do md  ...

这个问题我也没有深入研究过,经测试发现,其实可以不带,估计被你的写法误导了。只要去掉最前面开头的\就可以了,简单的说if exist 或者 xcopy 后面必须是文件名开头,不能以\开头,比如
  1. if exist "PE\%%a\WXPE\%%a.wim" xcopy "PE\%%a" "%name%:" /s /e /i /y
复制代码
这样就可以了,或者完整路径

  1. if exist "%~dp0\PE……
复制代码

  1. if exist ".\PE……
复制代码


描述可能不太对,理解就行,以上是简单研究的结果,未深入


作者: 青青草    时间: 2017-2-17 18:30
本帖最后由 青青草 于 2017-2-17 18:39 编辑
nttwqz 发表于 2017-2-17 17:58
这个问题我也没有深入研究过,经测试发现,其实可以不带,估计被你的写法误导了。只要去掉最前面开头的\ ...


if exist "PE\%%a\WXPE\%%a.wim" xcopy "PE\%%a" "%name%:" /s /e /i /y
这种写法,跟我在20#问你的写法:

在批处理当前目录下
for %%a in (i386-pc i386-efi x86_64-efi locale fonts) do md out\boot\grub\%%a
这样可以。
同样在批处理当前目录下
for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 7PEX64 7PEX86) do
if exist "PE\%%a\WXPE\%%a.wim" xcopy "PE\%%a" "%name%:" /s /e /i /y
这样就不可以。
for %%a in (10PEX64 10PEX86 8.1PEX64 8.1PEX86 7PEX64 7PEX86) do if exist "%~dp0\PE\%%a\WXPE\%%a.wim" xcopy "%~dp0\PE\%%a" "%name%:" /s /e /i /y
可以。

是一模一样的呀!
这样写法,不可以呀!

我最起初就是这样写的,但不行,所以就放弃了。也不知道这种写法,究竟错在哪了?


作者: nttwqz    时间: 2017-2-17 20:11
青青草 发表于 2017-2-17 18:30
if exist "PE\%%a\WXPE\%%a.wim" xcopy "PE\%%a" "%name%:" /s /e /i /y
这种写法,跟我在20#问你的写 ...

我试了一下,没问题啊,你确定之前已经pushd %~dp0 ???

如果没有,正常系统下,直接运行,当前目录,右键管理员运行 c:\windows\system32

加个 echo %cd%看下批处理运行的当前目录
作者: 青青草    时间: 2017-2-17 23:12
nttwqz 发表于 2017-2-17 20:11
我试了一下,没问题啊,你确定之前已经pushd %~dp0 ???

如果没有,正常系统下,直接运行,当前目录 ...

不好意思,找到原因了!
我是在txt文本文档中,写完批处理,检查无误后,保存,再将txt改为bat的。
改完后直接运行批处理,结果就是不行。
原以为,是批处理写错的原因,所以,也就没有再检查,而直接把批处理删除了!
今天,我详细检查了bat批处理,结果发现,有些行中多了两个?,有些行甚至有好几个? 。
问题就出在这了。把这些?删除后,就 OK 了!呵呵。
不好意思,麻烦你了!


作者: nttwqz    时间: 2017-2-18 08:52
青青草 发表于 2017-2-17 23:12
不好意思,找到原因了!
我是在txt文本文档中,写完批处理,检查无误后,保存,再将txt改为bat的。
改 ...

批处理就这点不好,运行不能准确提示哪一行代码错误,弄不好直接一闪而过,有次我就觉得代码都没问题但就是一闪而过,排查了一个小时才发现少打了个符号……
作者: slore    时间: 2017-2-18 09:32
cmd下调用x.bat,开头用echo on,文件删除操作之类的出错非常明显,用echo先跑dryrun
作者: 青青草    时间: 2017-2-18 12:35
nttwqz 发表于 2017-2-18 08:52
批处理就这点不好,运行不能准确提示哪一行代码错误,弄不好直接一闪而过,有次我就觉得代码都没问题但就 ...

是啊,在将txt转成bat并保存的过程中,不知不觉,每一行竟然多出了好几个“?” ,导致批处理一闪而过。还一直以为是批处理语句中哪里出错了!
这下好了,也可以这样写:
for /r PE %%d in (*.WIM) do xcopy PE\%%~nd %name%: /s /e /i /y
作者: 青青草    时间: 2017-2-18 12:40
slore 发表于 2017-2-18 09:32
cmd下调用x.bat,开头用echo on,文件删除操作之类的出错非常明显,用echo先跑dryrun

用echo先跑dryrun,的确是个好方法!
这下好了,也可以这样写:
for /r PE %%d in (*.WIM) do xcopy PE\%%~nd %name%: /s /e /i /y




欢迎光临 无忧启动论坛 (http://wuyou.net/) Powered by Discuz! X3.3