Moving files to existing subfolders based on part of the file name using the switch statement for matching?

I have a folder filled with a bunch of log files that need to be moved to subfolders so often. For example, I need to get the following files in directories in the direction of the arrow.

SOME_FILE_341213.txt → SMPROD
SOME_FILE_341242.txt → SMPROD
OTHER_FILE_13423.log → SSBRPRD
ALTER_FILE_13423.log → SSBRPRD
geofile12321 → REGIONPROD

I have seen many solutions that will parse a portion of a file name and move it to a directory containing this parsing of the file name. In my case, the destination directories will not match the matching part of the file names. I thought I could use the switch statement to match the first 4 or 5 letters in cases that would move the files to the corresponding directories, but I'm not sure what the most efficient way to do this. I would have about 25 cases to match. For files that do not correspond to any case, I would leave them where they are. Any tips?

+4
source share
4 answers

I would go with the switch statement in each loop. Something like that:

$Files = Dir c:\test foreach ($file in $files) { switch ($file.ToString().Substring(0,2)) { "te" {Write-Host "te"; break} "li" {Write-Host "li"; break} "ts" {Write-Host "ts"; break} } #End switch } #End foreach 

In the substring(x,y) command overload:

  • x = start character
  • y = number of characters to move

Obviously replace write-host with what you really want to do. The switch statement can span multiple lines. Do not forget to break at the end, so you are not looking at all 25 parameters for each file.

+1
source

There is nothing wrong with the switch. Personally, for something like this, I would prefer a hash table. Sort of:

 $dirInfo = @{'SOME' = 'SMPROD'; 'OTHE' = 'SSBRPRD'; 'ALTE' = 'SSBRPRD'; 'GEOF' = 'REGIONPROD' } $prefix = $file.Name.Substring(0,4).ToUpper() if($dirInfo.ContainsKey($prefix)){ $moveDir = 'C:\PATH\TO\SOMEFOLDER\{0}' -f $dirInfo[$prefix] Move-Item $file $moveDir } 
+1
source

Instead of hard code, the switch statement, I would probably build a hash table from a text file containing pairs of key values; this would mean that anyone new to Powershell could administer the file name / destination relationship. I'm not sure if this will be more efficient, but that means you do not need to update the script if and when the file or destination names change.

Here is a quick example ... it does not do any copying but demonstrates a method:

 $hashData = ConvertFrom-StringData ([IO.File]::ReadAllText("c:\temp\_sotemp\_hash\hashfile.txt")) $directory = 'C:\Temp\_sotemp' Get-ChildItem $directory | where {!($_.PsIsContainer)} | Foreach-Object { Foreach ($key in $hashData.GetEnumerator()){ if ($_.name.substring(0,7) -eq $key.Name){ Write-Host $_.fullname " will be copied to: " $key.Value } } } 

A few comments. First, do not use CMDLet Get-Content to read a text file containing key value pairs, as it can do some strange things for hash tables - you can get hash hashes! Secondly, the substring method will throw an error if you pass a file name with less than 7 characters - can you handle this?

Here is the contents of the text file:

 geofile=c:\\temp\\_sotemp\\REGIONPROD other_f=c:\\temp\\_sotemp\\SSBRPRD alter_f=c:\\temp\\_sotemp\\SSBRPRD some_fi=c:\\temp\\_sotemp\\SMPROD 
+1
source

Another version of the switch.

 Get-ChildItem "C:\temp" | foreach { switch -regex ($_.Name) { "^g.+" { write-output "$_.Name --> REGIONPROD"; break } "^S.+" { write-output "$_.Name --> SMPROD" ; break } "^[O|A].+" { write-output "$_.Name --> SSBRPRD" ; break } } } 

And another version of the hash with the target directories from the file.

 $hash = @{} Get-Content C:\temp\hashData.txt | foreach { if ($_ -notmatch "^$") { $fn, $dn = $_.split("|"); $hash.Add($fn, $dn) } } Get-ChildItem "C:\temp" | foreach { $fn = $_.Name.Substring(0,2) Write-Host "$_.Name --> " $hash.Item($fn) } 

Here is the hashData.txt file that I used for testing.

  So | SMPROD 
 Ot | SSBRPRD 
 Al | SSBRPRD 
 Ge | REGIONPROD

+1
source

Source: https://habr.com/ru/post/1442119/


All Articles