拖放多个文件的批处理文件?

Cha*_*eus 28 optimization png image batch-file

我写了一个批处理文件,当我将它拖放到批处理文件时,使用PngCrush来优化.png图像.

在接下来的部分中,我写了一篇关于我认为对批处理文件的良好升级的文章.

我的问题是:是否可以像在帖子中那样创建批处理文件,但能够一次优化多个图像?拖放多个.png文件?(并且输出类似于new.png,new(1).png,new(2).png等...

Joe*_*oey 43

是的,当然这是可能的.在批处理文件上拖动多个文件时,您将获取已删除文件的列表作为以空格分隔的列表.您可以使用以下简单批处理来验证这一点:

@echo %*
@pause
Run Code Online (Sandbox Code Playgroud)

现在您有两个选择:

  1. PngCrush已经可以在命令行上处理给它的多个文件名.在这种情况下,您所要做的就是传递%*给PngCrush而不仅仅是%1(正如您现在所做的那样):

    @pngcrush %*
    
    Run Code Online (Sandbox Code Playgroud)

    %*包含批处理文件的所有参数,因此这是将所有参数传递给另一个程序的便捷方法.但要注意名为PngCrush选项的文件.UNIX极客会知道这个问题:-)

    但是,在阅读了描述您的技术的帖子之后,当您将压缩文件写入时,这将无法正常工作new.png.如果你一次处理多个文件是一个坏主意,因为只有一个new.png:-).但我刚试过PngCrush很好地处理多个文件,所以如果你不介意文件的就地更新然后放

    @pngcrush -reduce -brute %*
    
    Run Code Online (Sandbox Code Playgroud)

    进入您的批处理将完成工作(按照您的原始文章).

  2. PngCrush不会处理多个文件,或者您希望在压缩后将每个图像写入新文件.在这种情况下,您坚持使用"一次一个文件"例程,但循环输入参数.在这种情况下,shift每次处理一个循环时,最简单的方法是构建一个小循环和参数:

    @echo off
    if [%1]==[] goto :eof
    :loop
    pngcrush -reduce -brute %1 "%~dpn1_new%~x1"
    shift
    if not [%1]==[] goto loop
    
    Run Code Online (Sandbox Code Playgroud)

    我们在这里做的很简单:首先,如果没有参数运行,我们跳过整个批处理,然后我们定义一个标签跳转到:loop.在里面我们只是在第一个参数上运行PngCrush,为压缩文件提供一个新名称.您可能想要阅读我在此处使用的路径剖析语法help call.基本上我在这里做的就是像以前一样命名文件; 我只是将"_new"粘贴到文件名的末尾(扩展名之前).%~dpn1扩展到驱动器,路径和文件名(不带扩展名),同时%~x1扩展到扩展名,包括点.

    ETA: Eep,我只是用new.png,new(1).png等读取你想要的输出.在这种情况下,我们不需要任何花哨的路径解剖,但我们还有其他需要注意的问题.

    最简单的方法可能是在我们处理第一个文件之前在0处启动一个计数器,并在每次处理另一个文件时递增它:

    @echo off
    if [%1]==[] goto :eof
    set n=0
    :loop
    if %n%==0 (
        pngcrush -reduce -brute %1 new.png
    ) else (
        pngcrush -reduce -brute %1 new^(%n%^).png
    )
    shift
    set /a n+=1
    if not [%1]==[] goto loop
    
    Run Code Online (Sandbox Code Playgroud)

    %n%是我们的计数器,我们n通过将结果写入new.png而不是来处理0 的情况new(0).png.

    不过,这种方法存在问题.如果已经有文件命名new.png,new(x).png那么你可能会破坏它们.不太好.所以我们必须做一些不同的事情并检查我们是否可以实际使用文件名:

    rem check for new.png
    if exist new.png (set n=1) else (set n=0 & goto loop)
    rem check for numbered new(x).png
    :checkloop
    if not exist new^(%n%^).png goto loop
    set /a n+=1
    goto checkloop
    
    Run Code Online (Sandbox Code Playgroud)

    程序的其余部分保持不变,包括正常循环.但现在我们从第一个未使用的文件名开始,避免覆盖已存在的文件.

随意根据需要进行调整.


jeb*_*jeb 10

要以安全的方式进行拖放操作,批处理并不是那么简单.

用处理%1,shift%*可能会失败,因为探险家是不是很聪明,而引用的文件名,只能用空格的文件名被引用.
但是Cool&stuff.png浏览器没有引用这样的文件,所以你得到一个cmdline就好了

pngCr.bat Cool&stuff.png
Run Code Online (Sandbox Code Playgroud)

所以%1只有Cool甚至%*只是Cool,但批次结束后,CMD.EXE试图执行一个stuff.png(和失败).

要处理这个问题,您可以使用!cmdcmdline!而不是%1.. 来访问参数%n,并且在执行结束时绕过潜在的错误,这很简单exit可以提供帮助.

@echo off
setlocal ENABLEDELAYEDEXPANSION
rem Take the cmd-line, remove all until the first parameter
set "params=!cmdcmdline:~0,-1!"
set "params=!params:*" =!"
set count=0

rem Split the parameters on spaces but respect the quotes
for %%G IN (!params!) do (
  set /a count+=1
  set "item_!count!=%%~G"
  rem echo !count! %%~G
)

rem list the parameters
for /L %%n in (1,1,!count!) DO (
  echo %%n #!item_%%n!#
)
pause

REM ** The exit is important, so the cmd.ex doesn't try to execute commands after ampersands
exit
Run Code Online (Sandbox Code Playgroud)

顺便说一句.尽管"标准"批次行限制为~8192个字符,但拖放操作的行限制为~2048个字符.
对于每个文件传递完整路径,可以使用少量文件达到此限制.

  • 是否对任何Windows版本特定的~2048拖放字符限制?我似乎能够在Win7上访问最多~8191个拖放字符. (2认同)

Amr*_*Ali 5

FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)
Run Code Online (Sandbox Code Playgroud)

为了区分丢弃的文件和文件夹,您可以使用:

FOR %%I IN (%*) DO (
    ECHO.%%~aI | FIND "d" >NUL
    IF ERRORLEVEL 1 (
        REM Processing Dropped Files
        CALL :_jobF "%%~fI"
    ) ELSE (
        REM Processing Dropped Folders
        CALL :_jobD "%%~fI"
    )
)
Run Code Online (Sandbox Code Playgroud)