4

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

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

4 回答 4

0

我可能不会从包含键值对的文本文件中构建一个哈希表,而不是硬编码 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 个字符,子字符串方法将引发错误 - 您可能想要处理这个问题?

这是文本文件的内容:

geofile=c:\\temp\\_sotemp\\REGIONPROD
other_f=c:\\temp\\_sotemp\\SSBRPRD
alter_f=c:\\temp\\_sotemp\\SSBRPRD
some_fi=c:\\temp\\_sotemp\\SMPROD
于 2012-10-25T17:57:04.087 回答
0

另一个开关版本。


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。

所以|SMPROD
OT|SSBRPRD
铝|SSBRPRD
锗|地区产品

于 2012-10-25T18:09:27.190 回答
0

我会在 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 = 要提取的字符数

显然用write-host你真正想要做的替换。switch 语句可以跨越多行。不要忘记break最后的 ,因此您不会为每个文件浏览所有 25 个选项。

于 2012-10-25T17:51:04.287 回答
0

开关没有问题。对于这样的事情,我个人更喜欢哈希表。就像是:

$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
}
于 2012-10-25T17:51:39.720 回答