问题
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
-Directoryswitch 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.
- Compatibility note: As Mofi, the original author of the batch-file code in the question, points out, the
The Move-Item command uses a delay-bind script block to determine the destination (target) directory for each input directory:
New-Item
-Type Directoryeither creates the target directory or - thanks to-Forcereturns an existing one. In both cases, a System.IO.DirectoryInfo instance is output, which tellsMove-Itemwhere 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]
- 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
[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