使用switch语句将文件移动到基​​于部分文件名的现有子文件夹中进行匹配?

时间:2012-10-25 16:44:03

标签: powershell switch-statement

我有一个文件夹,里面装满了一堆日志文件,需要经常移动到子文件夹中。例如,我需要将以下文件放入箭头的目录中。

SOME_FILE_341213.txt - > SMPROD
SOME_FILE_341242.txt - > SMPROD
OTHER_FILE_13423.log - > SSBRPRD
ALTER_FILE_13423.log - > SSBRPRD
geofile12321 - > REGIONPROD

我已经看到很多解决方案将解析文件名的一部分并将其移动到包含文件名解析的目录中。在我的例子中,目标目录不会真正匹配文件名的解析部分。我以为我可以使用switch语句将前4或5个字母与将文件移动到相应目录中的情况相匹配,但我不确定这是最有效的方法。我会有大约25个案例来匹配。对于任何情况都不匹配的文件,我会将它们保留在原来的位置。有什么建议吗?

4 个答案:

答案 0 :(得分:1)

我会在for-each循环中使用switch语句。像这样:

$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

substring(x,y)命令上,重载是:

  1. x =起始字符
  2. y =要拉的字符数
  3. 显然将write-host替换为您实际想要做的事情。 switch语句可以跨越多行。不要忘记最后的break,因此您不会浏览每个文件的所有25个选项。

答案 1 :(得分:1)

开关没有问题。就个人而言,我更喜欢哈希表。类似的东西:

$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
}

答案 2 :(得分:1)

我可能会从包含键值对的文本文件中构建一个哈希表,而不是硬编码一个switch语句。这意味着任何不熟悉Powershell的人都可以管理文件名/目标关系。我不确定这会更有效,但这意味着如果文件名或目的地发生变化,您就不必更新脚本。

这是一个快速示例......它不进行任何复制,但演示了方法:

$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
        }
    }
}

有几点需要注意。首先,不要使用Get-Content CMDLet来读取包含键值对的文本文件,因为它可以对哈希表做一些奇怪的事情 - 你最终可能会得到散列哈希值!其次,如果你传递一个少于7个字符的文件名,substring方法会抛出一个错误 - 你可能想要处理这个吗?

这是文本文件内容:

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

答案 3 :(得分:1)

另一个交换机版本。


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 }
   }
}

另一个哈希版本,包含文件中的目标目录。


$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)
}

这是我用于测试的hashData.txt。

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