Move the folder that does not contain inside a specific folder name
Moderators: Hacker, petermad, Stefan2, white
Move the folder that does not contain inside a specific folder name
Hello, I have over 1 TB of files to transfer.
What is the easiest way to solve this problem?
I would like to move project folders that do not contain a folder named PRINT inside.
I would also like to keep the folder structure: BRAND/PROJECT NAME
Folder structure explanation below:
Image: https://i.imgur.com/jqh4NwX.jpeg
What is the easiest way to solve this problem?
I would like to move project folders that do not contain a folder named PRINT inside.
I would also like to keep the folder structure: BRAND/PROJECT NAME
Folder structure explanation below:
Image: https://i.imgur.com/jqh4NwX.jpeg
Re: Move the folder that does not contain inside a specific folder name
If I understood it correctly it should be easy to achieve. In the copy/move dialog enter this into the field "Only files of this type":This excludes every directory named "print" regardless of where it appears.
Code: Select all
*.* | print\
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64
Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64
Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Re: Move the folder that does not contain inside a specific folder name
That's not what he wants. He want to move all <brand>\<project> folders that do not contain a <brand>\<project>\PRINT folder. And he wants to retain the <brand>\<project> folder structure.Dalai wrote: 2024-12-13, 12:38 UTC This excludes every directory named "print" regardless of where it appears.
Probably the easiest way is to use a script of some kind. For example a batch file like this:
Code: Select all
@echo off
setlocal
set "sourceFolder=c:\test\MAIN_DIRECTORY"
set "destFolder=d:\test\MAIN_DIRECTORY"
for /d %%b in ("%sourceFolder%\*") do (
:: %%b holds the name of the current brand folder
for /d %%p in ("%%b\*") do (
:: %%p holds the name of the current project folder
if not exist "%%p\PRINT" (
echo Moving "%%p" to "%destFolder%\%%~nxb\%%~nxp"
robocopy "%%p" "%destFolder%\%%~nxb\%%~nxp" /E /MOVE /NFL /NDL /NJH /NJS
)
)
)
endlocal
pause
Re: Move the folder that does not contain inside a specific folder name
Button code:
Code: Select all
TOTALCMD#BAR#DATA
%ComSpec% /q/c for /d %d in (*) do for /d %p in ("%~fd\*") do if not exist "%~fp\print\" >nul robocopy "%~fp"
"%T%%d\%%~nxp" /move /e /ndl /nfl /njh /njs
wcmicon2.dll,50
Move *\<subfolders> where there is no *\<subfolder>\print\ to the target panel
1
Overquoting is evil! 👎
Re: Move the folder that does not contain inside a specific folder name
PowerShell-based solution:
What it does:
Moves content of 'BRAND\PROJECT NAME' from the $oldLocation to the $newLocation wherever its path does not contain any subfolder named 'print', and preserves original directories structure.
Code: Select all
$oldLocation = 'x:\oldLocation\BRAND\PROJECT NAME'
$newLocation = 'y:\newLocation\BRAND\PROJECT NAME'
Get-ChildItem $oldLocation -recurse -force -file | Where {($_.FullName.Split('\')) -NotContains 'print'} | foreach {
$destination = $newLocation + $_.FullName.SubString($oldLocation.Length)
if (-not ($destination|Test-Path)) {New-Item -type file -path $destination -force}
Move-Item $_.FullName -destination $destination -force}
Moves content of 'BRAND\PROJECT NAME' from the $oldLocation to the $newLocation wherever its path does not contain any subfolder named 'print', and preserves original directories structure.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Re: Move the folder that does not contain inside a specific folder name
Note.
The above solutions have a drawback: all the folders' special attributes will be lost.
This is a regular robocopy behavior (see https://ghisler.ch/board/viewtopic.php?p=423718#p423718).
The initial PowerShell script was made without keeping this in mind, too.
However, sometimes it matters.
So here's an update:
PowerShell-based solution v2:
What it does:
Moves contents of 'BRAND\PROJECT NAME' from the $oldLocation to the $newLocation wherever its path does not contain any subfolder named 'print', preserving both the original directories structure and the original folders' attributes.
All data behind 'print' subfolders are being kept intact in the original location.
The above solutions have a drawback: all the folders' special attributes will be lost.
This is a regular robocopy behavior (see https://ghisler.ch/board/viewtopic.php?p=423718#p423718).
The initial PowerShell script was made without keeping this in mind, too.
However, sometimes it matters.
So here's an update:
PowerShell-based solution v2:
What it does:
Moves contents of 'BRAND\PROJECT NAME' from the $oldLocation to the $newLocation wherever its path does not contain any subfolder named 'print', preserving both the original directories structure and the original folders' attributes.
All data behind 'print' subfolders are being kept intact in the original location.
Code: Select all
$oldLocation = 'x:\oldLocation\BRAND\PROJECT NAME' # put here path to the actual 'old' contents location root
$newLocation = 'y:\newLocation\BRAND\PROJECT NAME' # put here path to the desired 'new' contents location root
# !!! the below line is for testing purposes only : otherwise remove or comment it
. $PSScriptRoot\moveItem_MovePathTest_tempEnvironment.ps1
# ^^^ the above line is for testing purposes only : otherwise remove or comment it
# defining required source contents excluding paths that contain a sub-folder named 'print'
Get-ChildItem $oldLocation -recurse -force | Where {$_.FullName.Split('\') -NotContains 'print'} | foreach {
# defining source path depending on whether a file or a folder is being piped
if ($_ -is [IO.DirectoryInfo]) {$source = [IO.DirectoryInfo]($_.FullName)}
if ($_ -is [IO.FileInfo]) {$source = [IO.DirectoryInfo]($_.DirectoryName)}
# defining destination path
[IO.DirectoryInfo]$destination = $newLocation + $source.toString().SubString($oldLocation.Length)
# making destination folder if it did not exist, and restoring original folder attributes
if (-not ($destination|Test-Path)) {New-Item -path $destination -type directory -force | Out-Null
$destination.Attributes = $source.Attributes}
$source | Write-Host -f Yellow
$destination | Write-Host -f DarkCyan
# moving contents to new location
$path = $source.toString()+'\*'
Move-Item -path $path -destination $destination -force # -verbose # -whatIf
''
}
# clean-up: remove empty folders that Move-Item might left behind in $oldLocation
Get-ChildItem $oldLocation -force -recurse -EA Silent|Where {$_.PSIsContainer -and @(Get-ChildItem -literal $_.FullName -force -recurse -EA Silent|Where {!$_.PSIsContainer}).Length -eq 0}|Remove-Item -force -recurse -EA Silent
moveItem_MovePathTest_tempEnvironment.ps1 child script for testing (if needed)
Code: Select all
# This script is to quickly create a minimally sufficient testing environment within the user's temporary directory ($env:Temp) to see how the main script works
$oldLocation = 'x:\oldLocation\BRAND\PROJECT NAME'
$newLocation = 'y:\newLocation\BRAND\PROJECT NAME'
$tempArea = [IO.Path]::combine($env:Temp,'moveItem')
$oldLocation = $oldLocation.Replace('x:',$tempArea)
$newLocation = $newLocation.Replace('y:',$tempArea)
$file = $oldLocation+'\notprint\notprint_file.txt';if (!($file|Test-Path)) {New-Item $file -type file -force -value $file > $null}
$file = $oldLocation+'\preprint\preprint_file.txt';if (!($file|Test-Path)) {New-Item $file -type file -force -value $file > $null}
$file = $oldLocation+'\print\print_file.txt'; if (!($file|Test-Path)) {New-Item $file -type file -force -value $file > $null}
$hereString = @"
[.ShellClassInfo]
IconResource=%SystemRoot%\system32\shell32.dll,122
"@
$file = $oldLocation+'\readOnly\desktop.ini'
if (!($file|Test-Path)){
New-Item $file -type file -force -value $hereString > $null
attrib ($file|Split-Path -parent) +r /d > $null
}
$cleanup = $tempArea+'\newLocation'
if (Test-Path $cleanup) {
Get-ChildItem $cleanup -recurse -force|Remove-Item -recurse -force -EA:Silent
Remove-Item $cleanup -recurse -force -EA:Silent}
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Re: Move the folder that does not contain inside a specific folder name
Different solutions from mine have another equally important drawback - they are not directly related to TC and, as a result, to this forum.

Overquoting is evil! 👎
Re: Move the folder that does not contain inside a specific folder name
2Fla$her
I believe this is not the way this board works.
Respecting the specifics of the use case requested here, I don't think a user would perform the operation on an everyday basis.
It's rather a kind of a yearly task if not a once-in-lifetime one.
Therefore, from my point of view, it's much safer for a user to use a standalone script to move a terabyte of data here and there.
Otherwise, that's not a big deal to wrap such a solution as, for example, my PowerShell script, into a TotalCommander interface.
Adapted PowerShell script:
moveProject_butPrint.ps1
User command (usercmd.ini)
User button
Prerequisites for 100% success
- a user must keep 'BRAND' root folder somewhere under the TotalCommander's active pane path, the closer to it the better.
- the TotalCommander's target pane path should somehow correspond to the desired destination.
Video illustration:
https://i.imgur.com/hVVW70d.mp4
This is how it works.
I believe this is not the way this board works.
Respecting the specifics of the use case requested here, I don't think a user would perform the operation on an everyday basis.
It's rather a kind of a yearly task if not a once-in-lifetime one.
Therefore, from my point of view, it's much safer for a user to use a standalone script to move a terabyte of data here and there.
Otherwise, that's not a big deal to wrap such a solution as, for example, my PowerShell script, into a TotalCommander interface.
Adapted PowerShell script:
moveProject_butPrint.ps1
Code: Select all
# when running this script standalone:
# put here the literal locations required for the standalone script use
$oldLocation = 'x:\oldLocation\BRAND\PROJECT NAME' # root path to the actual 'old' contents location
$newLocation = 'y:\newLocation\BRAND\PROJECT NAME' # root path to the desired 'new' contents location
# when running this script within a TotalCommander command:
# the locations would be defined from the %P %T parameters passed to the script by TotalCommander
if ($args){
$oldLocation = $args[0]
$newLocation = $args[1]
$oldLocation = $oldLocation.substring(0,$oldLocation.length -1)
$newLocation = $newLocation.substring(0,$newLocation.length -1)}
# defining required source contents excluding paths that contain a sub-folder named 'print'
Get-ChildItem $oldLocation -recurse -force -file| Where {$_.FullName.Split('\') -NotContains 'print'} | foreach {
# defining source path depending on whether a file or a folder is being piped
if ($_ -is [IO.DirectoryInfo]) {$source = [IO.DirectoryInfo]($_.FullName)}
if ($_ -is [IO.FileInfo]) {$source = [IO.DirectoryInfo]($_.DirectoryName)}
$source | Write-Host -f Yellow
# defining destination path
[IO.DirectoryInfo]$destination = $newLocation + $source.toString().SubString($oldLocation.Length)
# making destination folder if it did not exist, and restore original folder attributes
if (-not ($destination|Test-Path)) {New-Item -path $destination -type directory -force | Out-Null
$destination.Attributes = $source.Attributes}
$destination | Write-Host -f DarkCyan
# moving contents to new location
$path = $source.toString()+'\*'
Move-Item -path $path -destination $destination -force # -verbose # -whatIf
''
}
# clean-up: remove empty folders that Move-Item might left behind in $oldLocation
Get-ChildItem $oldLocation -force -recurse -EA Silent|Where {$_.PSIsContainer -and @(Get-ChildItem -literal $_.FullName -force -recurse -EA Silent|Where {!$_.PSIsContainer}).Length -eq 0}|Remove-Item -force -recurse -EA Silent
Code: Select all
[em_test_moveProject_butPrint]
cmd=pwsh -c "%commander_path%\Plugins\PowerShell\moveProject_butPrint.ps1"
param=%P %T
Code: Select all
TOTALCMD#BAR#DATA
em_test_moveProject_butPrint
WCMICONS.DLL
Move Project excluding Print(s)
-1
- a user must keep 'BRAND' root folder somewhere under the TotalCommander's active pane path, the closer to it the better.
- the TotalCommander's target pane path should somehow correspond to the desired destination.
Video illustration:
https://i.imgur.com/hVVW70d.mp4
This is how it works.
Last edited by beb on 2024-12-18, 07:26 UTC, edited 1 time in total.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Re: Move the folder that does not contain inside a specific folder name
Ohhhhhh thank you very much for your help! It saved me hours of my life. The only thing left for me is to hunt down the folders that don't fit the above conditions.
It actually worked and I was inspired to learn file management in powershell.
Re: Move the folder that does not contain inside a specific folder name
2pphktvmd
It's up to you to master any conditions to hunt down anything you want, using Where-Object as I did, or in any other way, for which PowerShell can be pretty flexible.
Get-ChildItem basics (see -include, -exclude, -filter, etc):
https://ss64.com/ps/get-childitem.html
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem
Where-Object basics:
https://ss64.com/ps/where-object.html
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object
Glad it worked for you.
Cheers.
It's up to you to master any conditions to hunt down anything you want, using Where-Object as I did, or in any other way, for which PowerShell can be pretty flexible.
Get-ChildItem basics (see -include, -exclude, -filter, etc):
https://ss64.com/ps/get-childitem.html
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem
Where-Object basics:
https://ss64.com/ps/where-object.html
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object
Code: Select all
get-something | where-object {
$_.property1 -like "a*" -or
$_.property2 -like "b*" -and
$_.property1 -notlike "c*" -and
$_.property2 -notlike "d*" -and
$_.property4 -contents "e" -and
$_.property5 -notcontents "f" -or
$_.property8 -match ".*g.*" -and
$_.property0 -notmatch ".*h.*"
}
Cheers.
#278521 User License
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15
Total Commander [always the latest version, including betas] x86/x64 on Win10 x64/Android 10/15