从 .txt 列表批量创建符号 link

Batch symbolic link creation from .txt list

我需要一种方法来创建指向一个文件夹中多个文件的符号链接,所有这些文件都列在一个 .txt 文件中。列表中的文件名缺少文件扩展名。我曾经使用以下脚本进行复制,但未能将复制命令替换为符号链接创建。

@echo off

chcp 65001 > nul

for /f "usebackq delims=" %%i IN ("selection_list.txt") DO (
    xcopy "..\%%i.zip" "..\selection\%%i.zip*"
)

pause

使用相对路径,因为我希望能够在多个文件夹中使用它。 .txt 文件中的文件名不包括文件扩展名。 例如,假设我想在文件夹“F:\assets”中使用它,我会将我的脚本与名为 selection_list.txt 的 .txt 文件一起放在文件夹“F:\assets\selection_script”中。启动脚本后,它将创建一个文件夹“F:\assets\selection”,其中包含我想要的所有文件。

我尝试用 mklink /D 替换 xcopy 命令,使用这个语法示例

mklink /D "C:\Link To Folder" "C:\Users\Name\Original Folder"

新脚本如下所示

@echo off

chcp 65001 > nul

for /f "usebackq delims=" %%i IN ("selection_list.txt") DO (
    mklink /D "..\selection_links\%%i.zip*" "..\%%i.zip"
)

pause

显然这没有用。说系统找不到文件 selection_list.txt 我尝试手动 运行 具有相对路径的单个命名文件的命令并且它有效,所以我的问题是让它在带有列表的函数中工作。在我看来,将文件扩展名添加到 .txt 列表中的文件名之上可能是问题所在,但我不知道如何解决它。我尝试了一些我发现的语法变体,但没有成功

我对这方面还很陌生,所以任何帮助将不胜感激!

让我先解释一下要完成的任务。有以下文件夹和文件:

F:\assets

  • 选择
    • 开发与测试(!).zip
    • ;示例邮编 File.zip
  • selection_script
    • create_selection.cmd
    • selection_list.txt

文本文件 selection_list.txt 包含行:

Development & Test(!)
;Example Zip File
Not existing file

create_selection.cmd 的执行应该产生以下文件夹和文件:

F:\assets

  • 选择
    • 开发与测试(!).zip
    • ;示例邮编 File.zip
  • selection_links
    • 开发与测试(!).zip
    • ;示例邮编 File.zip
  • selection_script
    • create_selection.cmd
    • selection_list.txt

创建的目录 selection_links 中的目录条目 Development & Test(!).zip;Example Zip File.zip 是符号 link,而不是目录 selection 中两个文件的副本。

这个符号 link 的创建任务可以用 F:\assets\selection_script\create_selection.cmd 和以下命令行完成:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 >nul 2>&1
for %%I in ("%~dp0..\selection_links") do set "LinksFolder=%%~fI"

if not exist "%LinksFolder%\" md "%LinksFolder%" 2>nul
if not exist "%LinksFolder%\" echo ERROR: Failed to create directory: "%LinksFolder%"& goto EndBatch

pushd "%LinksFolder%"
if exist "%~dp0selection_list.txt" for /F "usebackq eol=| delims=" %%I in ("%~dp0selection_list.txt") do if exist "..\selection\%%I.zip" if not exist "%%I.zip" mklink "%%I.zip" "..\selection\%%I.zip" >nul
popd

:EndBatch
%SystemRoot%\System32\chcp.com %CodePage% >nul
endlocal

首先完全定义了所需的执行环境,前两个命令行设置本地执行环境,关闭命令回显模式,启用命令扩展并根据此任务的需要禁用延迟变量扩展。

接下来使用 Compo 在 DosTips 论坛主题 [Info] Saving current codepage 上发布的命令行确定当前活动的代码页并存储在环境变量 CodePage 中.然后将活动代码页更改为 UTF-8,尽管该示例并不是真正需要的。

接下来确定应在其中创建符号 link 的文件夹的完整路径,该文件夹 selection_links 是父文件夹 F:\assets 的子文件夹包含批处理脚本的文件夹 selection_script。在确定完全限定的文件夹名称时,此文件夹是否已存在无关紧要。

下一步验证目标文件夹是否存在。文件夹 selection_links 是在不存在的情况下创建的,并再次检查该文件夹现在是否确实存在。创建文件夹失败时输出一条有用的错误消息,批处理文件恢复初始代码页和初始执行环境。

通过使用命令 PUSHD 将目标文件夹设为当前目录,在验证目标文件夹存在后现在应该不会再失败了。

接下来处理文本文件 selection_list.txt 中引用其完全限定文件名的行,方法是使用 %~dp0 扩展到驱动器和参数 0 的路径,参数 0 是文件的完整路径批处理文件总是以反冲结尾。

不以字符 | 开头的每个 non-empty 行都被一个接一个完整地分配给循环变量 I。字符 | 对于文件名无效,如有关 Naming Files, Paths, and Namespaces 的 Microsoft 文档中所述。接下来验证文件夹 selection 中是否确实存在同名的 ZIP 压缩文件 file 并且当前文件夹 selection_links 中是否没有同名的目录条目].

如果这两个条件都为真,则执行MKLINK在当前目录selection_links创建一个文件符号link 到目录 selection.

中的 ZIP 文件

请注意 ZIP 存档 文件 不是目录,因此使用 MKLINK 选项 /D创建一个 目录 符号 link 永远无法工作。

最后使用POPD还原了初始当前目录,并且在结束前批处理文件也还原了初始代码页和初始执行环境。

为了了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /? ... 说明 %~dp0 ... 参数 0 的驱动器和路径 – 批处理文件路径
  • chcp /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • mklink /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?

另请参阅: