How to move folders into subfolders with name of first character of the folder to move with support for Unicode characters in folder names?

被刻印的时光 ゝ 提交于 2021-01-24 07:16:20

问题


I use this batch script written by Mofi to move folders into other folders.

@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

It moves folders with two or more characters in current folder into a subfolder with name being the first character of the folder to move with automatic creation of the destination folder if not existing already.

But the batch script doesn't work if a folder name contains one or more Unicode characters.

Is there a workaround with PowerShell?

For example, it doesn't move a folder with first character being Ш (Cyrillic capital letter SHA) into a folder with name Ш.


回答1:


Yes, PowerShell handles Unicode characters in file paths (and in general) correctly.

The equivalent of your batch-file code in PowerShell is:

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

Note: The -WhatIf common parameter in the command above previews the move operation. Remove -WhatIf once you're sure the operation will do what you want. However, even with
-WhatIf the target directories are created right away.

  • Get-ChildItem -Directory -Path ??* gets all directories whose name is made up of at least 2 characters.

    • Compatibility note: As Mofi, the original author of the batch-file code in the question, points out, the -Directory switch requires PowerShell version 3 or higher, and to make the code work in v2 as well,
      Get-ChildItem -Path ??* | Where-Object { $_.PSIsContainer } must be used.
  • The Move-Item command uses a delay-bind script block to determine the destination (target) directory for each input directory:

    • New-Item -Type Directory either creates the target directory or - thanks to -Force returns an existing one. In both cases, a System.IO.DirectoryInfo instance is output, which tells Move-Item where to move the input dir. at hand.

    • Join-Path determines the full target path from the input directory's own (parent) directory, $_.Parent.FullName[1], and the first-letter-of-the-input-dir-name target name, $_.Name[0])

      • Note: Constructing the full target path isn't strictly necessary if you're running the command in the current directory, so in this case you could simplify to
        New-Item -Type Directory -Force $_.Name[0]

[1] You can also use $_.PSParentPath, but, due to a bug in Join-Path in PowerShell [Core] as of 7.1, that wouldn't work on Unix-like platforms - see GitHub issue #14538.



来源:https://stackoverflow.com/questions/65564448/how-to-move-folders-into-subfolders-with-name-of-first-character-of-the-folder-t

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!