【问题标题】:How to move folders into subfolders with name of first character of the folder to move with support for Unicode characters in folder names?如何将文件夹移动到具有文件夹第一个字符名称的子文件夹中,以支持文件夹名称中的 Unicode 字符?
【发布时间】:2021-04-10 08:24:53
【问题描述】:

我使用Mofi 编写的batch script 将文件夹移动到其他文件夹中。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
%SystemRoot%\System32\tree.com
for /F "eol=| delims=" %%I in ('dir /AD /B 2^>nul') do (
    set "FolderName=%%I"
    setlocal EnableDelayedExpansion
    set "TargetFolder=!FolderName:~0,1!"
    if not "!TargetFolder!" == "!FolderName!" (
        md "!TargetFolder!" 2>nul
        move /-Y "!FolderName!" "!TargetFolder!\"
    )
    endlocal
)
%SystemRoot%\System32\tree.com
endlocal

它将当前文件夹中具有两个或多个字符的文件夹移动到名称为文件夹的第一个字符的子文件夹中,如果目标文件夹不存在,则会自动创建目标文件夹。

但如果文件夹名称包含一个或多个 Unicode 字符,批处理脚本将不起作用。

是否有使用 PowerShell 的解决方法?

例如,它不会将第一个字符为 Ш(西里尔大写字母 SHA)的文件夹移动到名称为 Ш 的文件夹中。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    是的,PowerShell 可以正确处理文件路径中的 Unicode 字符(通常情况下)。

    您在 PowerShell 中的批处理文件代码是:

    Get-ChildItem -Directory -Path ??* |
      Move-Item -Destination { 
        # Determine the target dir - the input dir's first letter -
        # ensure that it exists, and output it.
        New-Item -Type Directory -Force (Join-Path $_.Parent.FullName $_.Name[0])
      } -WhatIf
    

    注意:上面命令中的-WhatIf common parameter预览 移动操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf。但是,即使使用
    -WhatIf目标目录也会立即创建

    • Get-ChildItem -Directory -Path ??* 获取名称至少由 2 个字符组成的所有目录。

      • 兼容性说明:正如问题中批处理文件代码的原作者 Mofi 所指出的,-Directory 开关需要 PowerShell 版本 3 或更高版本,并且要使代码在 v2 中也能工作,
        必须使用Get-ChildItem -Path ??* | Where-Object { $_.PSIsContainer }
    • Move-Item 命令使用delay-bind script block 来确定每个输入目录的目标(目标)目录:

      • New-Item -Type Directory 要么创建目标目录,要么 - 感谢-Force 返回一个现有的。在这两种情况下,都会输出一个System.IO.DirectoryInfo 实例,它告诉Move-Item 将输入目录移动到哪里。就在眼前。

      • Join-Path 从输入目录自己的(父)目录$_.Parent.FullName[1] 和输入目录名的第一个字母确定完整的目标路径目标名称,$_.Name[0])

        • 注意:如果您在 current 目录中运行该命令,则不一定需要构建完整的目标路径,因此在这种情况下,您可以简化为
          New-Item -Type Directory -Force $_.Name[0]

    [1] 你也可以使用 $_.PSParentPath,但是,由于 PowerShell [Core] 中 Join-Path 中的一个错误,从 7.1 开始,这在类 Unix 平台上不起作用 - 请参阅 @987654329 @.

    【讨论】:

    • PowerShell 脚本可以在 PowerShell 3.0 或更高版本中正常工作。即使在 Windows 7 上默认安装 PowerShell 2.0 的 FAT32 驱动器上也能正常工作,第一行根据How do I get only directories using Get-ChildItem? 修改为Get-ChildItem -Path ??* | ?{ $_.PSIsContainer } | 感谢您将我的批处理代码重写为 PowerShell 脚本代码。
    • 感谢您的确认,@Mofi。我已将 v2 解决方法添加到答案中(幸运的是,v2 安装越来越少)。我还添加了一条注释,表明是您编写了批处理文件代码,OP 应该在问题中完成该代码。 (我已经用批处理文件代码 +1 给出了您的原始答案)
    • 我很感激,@JackRock。
    猜你喜欢
    • 2023-03-17
    • 2021-08-02
    • 2020-05-03
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    相关资源
    最近更新 更多