如何根据文件夹名称中的关键字将文件夹移动到其他文件夹?
How to move folders to other folders by grouping them according to a keyword present in the folder name?
将文件移动到它们的相关文件夹中,按文件中的关键字符串排序
Example script
我用这个脚本
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "SPLITCHAR=-" & rem // (a single character to split the file names)
set "SEARCHSTR=_" & rem // (a certain string to be replaced by another)
set "REPLACSTR= " & rem // (a string to replace all found search strings)
set "OVERWRITE=" & rem // (set to non-empty value to force overwriting)
rem // Get file location and pattern from command line arguments:
set "LOCATION=%~1" & rem // (directory to move the processed files into)
set "PATTERNS=%~2" & rem // (file pattern; match all files if empty)
rem /* Prepare overwrite flag (if defined, set to character forbidden
rem in file names; this affects later check for file existence): */
if defined OVERWRITE set "OVERWRITE=|"
rem // Continue only if target location is given:
if defined LOCATION (
rem // Create target location (surpress error if it already exists):
2> nul md "%LOCATION%"
rem /* Loop through all files matching the given pattern
rem in the current working directory: */
for /F "eol=| delims=" %%F in ('dir /B "%PATTERNS%"') do (
rem // Process each file in a sub-routine:
call :PROCESS "%%F" "%LOCATION%" "%SPLITCHAR%" "%SEARCHSTR%" "%REPLACSTR%"
)
)
endlocal
exit /B
:PROCESS
rem // Retrieve first argument of sub-routine:
set "FILE=%~1"
rem // Split name at (first) split character and get portion in front:
for /F "delims=%~3" %%E in ("%~1") do (
rem // Append a split character to partial name:
set "FOLDER=%%E%~3"
)
setlocal EnableDelayedExpansion
rem // Right-trim partial name:
if not "%~4"=="" set "FOLDER=!FOLDER:%~4%~3=!"
set "FOLDER=!FOLDER:%~3=!"
rem /* Check whether partial name is not empty
rem (could happen if name began with split character): */
if defined FOLDER (
rem // Replace every search string with another:
if not "%~4"=="" set "FOLDER=!FOLDER:%~4=%~5!"
rem // Create sub-directory (surpress error if it already exists):
2> nul md "%~2\!FOLDER!"
rem /* Check if target file already exists; if overwrite flag is
rem set (to an invalid character), the target cannot exist: */
if not exist "%~2\!FOLDER!\!FILE!%OVERWRITE%" (
rem // Move file finally (surpress `1 file(s) moved.` message):
1> nul move /Y "!FILE!" "%~2\!FOLDER!"
)
)
endlocal
exit /B
但我希望对文件夹而不是文件做类似的事情。
例如,我有这些 folders list
Absolute Moebius - Volume 2 - The Long Tomorrow
Absolute Moebius - Volume 3
Agenzia X - Volume 1 - La Recluta
Agenzia X - Volume 2 - Black Point
Agenzia X - Volume 3 - Soli
Akira - Volume 10
Akira - Volume 20
Akira - Volume 23
Alan Ford - Volume 11 - Il Numero Uno
Alan Ford - Volume 12 - La Triste Storia Di Un Giovane Ricco
Alan Ford - Volume 13 - Golf
我希望将它们移动到这样的文件夹结构中
Absolute Moebius [folder]
|
|---> Absolute Moebius - Volume 2 - The Long Tomorrow
|---> Absolute Moebius - Volume 3
|
|
Agenzia X [folder]
|
|---> Agenzia X - Volume 1 - La Recluta
|---> Agenzia X - Volume 2 - Black Point
|---> Agenzia X - Volume 3 - Soli
|
Akira [folder]
|
|---> Akira - Volume 10
|---> Akira - Volume 20
|---> Akira - Volume 23
|
.
.
:
通常许多文件夹名称包含 Volume
、 volume
或其他一些重复的关键字,可用作判别式
编辑:问题询问如何移动文件夹而不是文件。例如,上面的脚本在您移动 文件 并将它们分组到文件夹中时起作用:您可以看到一个示例 HERE。但我希望移动 文件夹 而不是文件,以便将它们分组到其他文件夹中,例如,使用关键字之类的条件,例如 Volume
字
我还添加了 Powershell 标签,因为对我来说,powershell 脚本也很好
这可以在 Powershell 中相当简单地完成。使用 Get-ChildItem
枚举目录,我们可以过滤特定的关键字,然后将它们通过管道传递给另一个 cmdlet。
#Filter for directories with the word "volume" in it
#Then pipe to a Foreach-Object loop to have it perform the same action
#over for the objects passed to it
Get-ChildItem -Path C:\some\path -Filter "*volume*" -Directory -Recurse | ForEach-Object -Process { Move-Item -Path $_.FullName -Destination C:\Some\OtherFolder }
根据您的 Posh 版本,您可以添加一个 -Directory
参数来仅列出目录并忽略文件。我还没有真正研究过 Move-Item
cmdlet,但是,这应该有效。
根据您的评论:
$Folder = Get-ChildItem -Path C:\Some\Path -Filter "*volume*" -Directory -Recurse #| ForEach-Object -Process { Move-Item -Path $_.FullName -Destination C:\Some\OtherFolder }
$Folder1 = $Folder.FullName.split('\')[-1]
$newFolder = "$($Folder1.Split(' ')[0])" + " $($Folder1.Split(' ')[1])"
If(-not (Test-Path -Path C:\Some\Path$newFolder)){
New-Item -Path C:\some\path -Name $newFolder -ItemType Directory -OutVariable Location
}
Foreach($Directory in $Folder.FullName){
Move-Item -Path $Directory -Destination $Location.FullName}
我看到你选择了一个答案。这是另一种方式。
# Setup test data
$Dirs = @(
'Absolute Moebius - Volume 2 - The Long Tomorrow'
,'Absolute Moebius - Volume 3'
,'Agenzia X - Volume 1 - La Recluta'
,'Agenzia X - Volume 2 - Black Point'
,'Agenzia X - Volume 3 - Soli'
,'Akira - Volume 10'
,'Akira - Volume 20'
,'Akira - Volume 23'
,'Alan Ford - Volume 11 - Il Numero Uno'
,'Alan Ford - Volume 12 - La Triste Storia Di Un Giovane Ricco'
,'Alan Ford - Volume 13 - Golf'
)
foreach ($Dir in $Dirs) {
if (-not (Test-Path -Path $Dir)) { New-Item -ItemType Directory -Path $Dir | Out-Null }
}
# Code to move files starts here vvvvvvvvvvvvvvvvvvvv
(Get-ChildItem -Directory -Filter '* - Volume*').Name |
ForEach-Object {
$NewDirName = $_.Split(' - ')[0]
if (-not (Test-Path -Path $NewDirName)) { New-Item -ItemType Directory -Path $NewDirName | Out-Null }
Move-Item -Path $_ -Destination $NewDirName
}
# Code to move files ends here ^^^^^^^^^^^^^^^^^^^
将文件移动到它们的相关文件夹中,按文件中的关键字符串排序
Example script
我用这个脚本
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "SPLITCHAR=-" & rem // (a single character to split the file names)
set "SEARCHSTR=_" & rem // (a certain string to be replaced by another)
set "REPLACSTR= " & rem // (a string to replace all found search strings)
set "OVERWRITE=" & rem // (set to non-empty value to force overwriting)
rem // Get file location and pattern from command line arguments:
set "LOCATION=%~1" & rem // (directory to move the processed files into)
set "PATTERNS=%~2" & rem // (file pattern; match all files if empty)
rem /* Prepare overwrite flag (if defined, set to character forbidden
rem in file names; this affects later check for file existence): */
if defined OVERWRITE set "OVERWRITE=|"
rem // Continue only if target location is given:
if defined LOCATION (
rem // Create target location (surpress error if it already exists):
2> nul md "%LOCATION%"
rem /* Loop through all files matching the given pattern
rem in the current working directory: */
for /F "eol=| delims=" %%F in ('dir /B "%PATTERNS%"') do (
rem // Process each file in a sub-routine:
call :PROCESS "%%F" "%LOCATION%" "%SPLITCHAR%" "%SEARCHSTR%" "%REPLACSTR%"
)
)
endlocal
exit /B
:PROCESS
rem // Retrieve first argument of sub-routine:
set "FILE=%~1"
rem // Split name at (first) split character and get portion in front:
for /F "delims=%~3" %%E in ("%~1") do (
rem // Append a split character to partial name:
set "FOLDER=%%E%~3"
)
setlocal EnableDelayedExpansion
rem // Right-trim partial name:
if not "%~4"=="" set "FOLDER=!FOLDER:%~4%~3=!"
set "FOLDER=!FOLDER:%~3=!"
rem /* Check whether partial name is not empty
rem (could happen if name began with split character): */
if defined FOLDER (
rem // Replace every search string with another:
if not "%~4"=="" set "FOLDER=!FOLDER:%~4=%~5!"
rem // Create sub-directory (surpress error if it already exists):
2> nul md "%~2\!FOLDER!"
rem /* Check if target file already exists; if overwrite flag is
rem set (to an invalid character), the target cannot exist: */
if not exist "%~2\!FOLDER!\!FILE!%OVERWRITE%" (
rem // Move file finally (surpress `1 file(s) moved.` message):
1> nul move /Y "!FILE!" "%~2\!FOLDER!"
)
)
endlocal
exit /B
但我希望对文件夹而不是文件做类似的事情。 例如,我有这些 folders list
Absolute Moebius - Volume 2 - The Long Tomorrow
Absolute Moebius - Volume 3
Agenzia X - Volume 1 - La Recluta
Agenzia X - Volume 2 - Black Point
Agenzia X - Volume 3 - Soli
Akira - Volume 10
Akira - Volume 20
Akira - Volume 23
Alan Ford - Volume 11 - Il Numero Uno
Alan Ford - Volume 12 - La Triste Storia Di Un Giovane Ricco
Alan Ford - Volume 13 - Golf
我希望将它们移动到这样的文件夹结构中
Absolute Moebius [folder]
|
|---> Absolute Moebius - Volume 2 - The Long Tomorrow
|---> Absolute Moebius - Volume 3
|
|
Agenzia X [folder]
|
|---> Agenzia X - Volume 1 - La Recluta
|---> Agenzia X - Volume 2 - Black Point
|---> Agenzia X - Volume 3 - Soli
|
Akira [folder]
|
|---> Akira - Volume 10
|---> Akira - Volume 20
|---> Akira - Volume 23
|
.
.
:
通常许多文件夹名称包含 Volume
、 volume
或其他一些重复的关键字,可用作判别式
编辑:问题询问如何移动文件夹而不是文件。例如,上面的脚本在您移动 文件 并将它们分组到文件夹中时起作用:您可以看到一个示例 HERE。但我希望移动 文件夹 而不是文件,以便将它们分组到其他文件夹中,例如,使用关键字之类的条件,例如 Volume
字
我还添加了 Powershell 标签,因为对我来说,powershell 脚本也很好
这可以在 Powershell 中相当简单地完成。使用 Get-ChildItem
枚举目录,我们可以过滤特定的关键字,然后将它们通过管道传递给另一个 cmdlet。
#Filter for directories with the word "volume" in it
#Then pipe to a Foreach-Object loop to have it perform the same action
#over for the objects passed to it
Get-ChildItem -Path C:\some\path -Filter "*volume*" -Directory -Recurse | ForEach-Object -Process { Move-Item -Path $_.FullName -Destination C:\Some\OtherFolder }
根据您的 Posh 版本,您可以添加一个 -Directory
参数来仅列出目录并忽略文件。我还没有真正研究过 Move-Item
cmdlet,但是,这应该有效。
根据您的评论:
$Folder = Get-ChildItem -Path C:\Some\Path -Filter "*volume*" -Directory -Recurse #| ForEach-Object -Process { Move-Item -Path $_.FullName -Destination C:\Some\OtherFolder }
$Folder1 = $Folder.FullName.split('\')[-1]
$newFolder = "$($Folder1.Split(' ')[0])" + " $($Folder1.Split(' ')[1])"
If(-not (Test-Path -Path C:\Some\Path$newFolder)){
New-Item -Path C:\some\path -Name $newFolder -ItemType Directory -OutVariable Location
}
Foreach($Directory in $Folder.FullName){
Move-Item -Path $Directory -Destination $Location.FullName}
我看到你选择了一个答案。这是另一种方式。
# Setup test data
$Dirs = @(
'Absolute Moebius - Volume 2 - The Long Tomorrow'
,'Absolute Moebius - Volume 3'
,'Agenzia X - Volume 1 - La Recluta'
,'Agenzia X - Volume 2 - Black Point'
,'Agenzia X - Volume 3 - Soli'
,'Akira - Volume 10'
,'Akira - Volume 20'
,'Akira - Volume 23'
,'Alan Ford - Volume 11 - Il Numero Uno'
,'Alan Ford - Volume 12 - La Triste Storia Di Un Giovane Ricco'
,'Alan Ford - Volume 13 - Golf'
)
foreach ($Dir in $Dirs) {
if (-not (Test-Path -Path $Dir)) { New-Item -ItemType Directory -Path $Dir | Out-Null }
}
# Code to move files starts here vvvvvvvvvvvvvvvvvvvv
(Get-ChildItem -Directory -Filter '* - Volume*').Name |
ForEach-Object {
$NewDirName = $_.Split(' - ')[0]
if (-not (Test-Path -Path $NewDirName)) { New-Item -ItemType Directory -Path $NewDirName | Out-Null }
Move-Item -Path $_ -Destination $NewDirName
}
# Code to move files ends here ^^^^^^^^^^^^^^^^^^^