如何在Windows 10批处理文件中对参数列表进行排序



我需要调用一个带有文件名列表的程序,但我需要按照排序顺序找到并提取列表上的第一个文件,然后将其余文件传递给程序。

具体来说,我想传递用QTTabbar应用程序启动器选择的文件列表,并执行exiftool,以便列表上的第一个文件用于"-TagsFromFile;选项,然后处理所有其余文件,使它们获得"-AllDates";选项已应用。所以我的第一次尝试是:

exiftool -TagsFromFile %1 -AllDates %*

这会将第一个文件放在列表中,但由于exiftool会将其设置为与现有值相同的值,因此这是可以接受的。

然而,我发现QTTabbar并没有像我预期的那样,按照名称的词法排序顺序将参数传递给批处理文件。所以我想我需要对清单进行排序。

我在How to sort the arguments drop to a batch file?中找到了对参数进行排序的方法?但在这个解决方案中,有一个循环,每个参数都会调用一个程序,而不是构建一个新的参数列表。

for /f "delims=" %%a in ('cmd /c ^"for %%i in ^(%*^) do @echo %%~i^"^|sort') do (
echo use "%%a"
)

代替";回声使用"%%"a";,我需要建立一个新的参数列表,可以将其传递给exiftool。理想情况下,我可以建立一个列表,然后用新的参数列表替换原来的参数列表,比如";设置";Bash中的命令。如果做不到这一点,我可以建立一个新的列表并使用它,但我不知道如何建立一个列表,如果我有第一个元素,我也不知道如何引用它。

我该怎么做?

编辑:这些文件是在文件资源管理器GUI中选择的。它们呈现给批处理文件的顺序由Windows决定。这里是"0"的输出;回声%*";来自批处理文件:

"C:Usersuser1DesktopsetAB.test0000920.jpg" "C:Usersuser1DesktopsetAB.test0000913.jpg" "C:Usersuser1DesktopsetAB.test0000914.jpg" "C:Usersuser1DesktopsetAB.test0000915.jpg" "C:Usersuser1DesktopsetAB.test0000916.jpg" "C:Usersuser1DesktopsetAB.test0000917.jpg" "C:Usersuser1DesktopsetAB.test0000918.jpg" "C:Usersuser1DesktopsetAB.test0000919.jpg"

如您所见,最后一个文件首先出现。我不知道为什么。有时它们的顺序相反。

因此,批处理文件被调用为:

ex.bat "C:Usersuser1DesktopsetAB.test0000920.jpg" "C:Usersuser1DesktopsetAB.test0000913.jpg" "C:Usersuser1DesktopsetAB.test0000914.jpg" "C:Usersuser1DesktopsetAB.test0000915.jpg" "C:Usersuser1DesktopsetAB.test0000916.jpg" "C:Usersuser1DesktopsetAB.test0000917.jpg" "C:Usersuser1DesktopsetAB.test0000918.jpg" "C:Usersuser1DesktopsetAB.test0000919.jpg"

我希望exiftool运行为:

exiftool -TagsFromFile "C:Usersuser1DesktopsetAB.test0000913.jpg" -AllDates "C:Usersuser1DesktopsetAB.test0000913.jpg" "C:Usersuser1DesktopsetAB.test0000914.jpg" "C:Usersuser1DesktopsetAB.test0000915.jpg" "C:Usersuser1DesktopsetAB.test0000916.jpg" "C:Usersuser1DesktopsetAB.test0000917.jpg" "C:Usersuser1DesktopsetAB.test0000918.jpg" "C:Usersuser1DesktopsetAB.test0000919.jpg" "C:Usersuser1DesktopsetAB.test0000920.jpg"

所以您的代码非常接近。您所需要添加的只是一些基本概念,以便将第一个参数放入变量中,这可以通过检查是否定义了变量来完成。然后使用SET命令将所有参数重新生成为另一个变量。如本问题所述,这需要延迟扩展。

@ECHO OFF
setlocal enabledelayedexpansion
set "first="
set "all="
for /f "delims=" %%a in ('cmd /c ^"for %%i in ^(%*^) do @echo %%~i^"^|sort') do (
if not defined first set "first=%%~a"
set "all=!all!"%%~a" "
)
exiftool -TagsFromFile "%first%" -AllDates %all%
endlocal

与Squashman已经提供的方法非常相似,但适用于包含!字符的文件路径。

@For %%G In (First Rest) Do @Set "%%G="
@For /F "Delims=" %%H In (
'"(For %%G In (%*) Do @Echo "%%~G") | %SystemRoot%System32sort.exe"'
) Do @If Not Defined First (Set "First=%%H") Else (SetLocal EnabledelayedExpansion
For /F "Delims=" %%I In ("!Rest!%%H") Do @EndLocal & Set "Rest=%%I")
exiftool.exe -TagsFromFile %First% -AllDates %Rest%

最新更新