【问题标题】:I'm trying to clean up a script I have by trying to make it build the folder structure based on the file name我正在尝试通过尝试使其基于文件名构建文件夹结构来清理我拥有的脚本
【发布时间】:2018-09-13 11:00:51
【问题描述】:

我目前有一个 powershell 脚本,可以根据文件名将文件移动到特定文件夹。脚本的开头是为一组文件应该去的目标路径设置一个变量:

$FileName = "path to where files with that name go"

然后我将整个文件目录的内容递归地读入一个变量中:

$Files = Get-ChildItem $FileFolder -File -Recurse

然后我有一堆相同的命令用于匹配和移动:

$Files | Where-Object { $_.Name -match 'some name' } | Move-Item -Destination "$Variable-set-above" -Force

当它是 10 或 20 匹配时很好,但是随着越来越多的文件被添加并需要组织,我想看看我是否可以通过让脚本构建目标文件夹结构来清理脚本文件名,而不是每个匹配情况都有一行,每次移动都有一行。

我正在研究Split-Path、正则表达式-splitString.split() 和其他一些选项,我想我已经接近了,但我找不到任何人拿第一部分的例子文件名,最多几个字符,保留第一部分,排除其余部分。有点像Split-Ignoresecond 或类似的东西。

我在修改我的主脚本之前先测试这样做,到目前为止我有这个:

文件夹中的 3 个文件名为 Test.One.File.D0001.txtTest.Two.File.D0001.txtTest.Three.File.D0001.txt

我的测试脚本:

$Testfiles = Get-ChildItem -Name *.txt
$Testfiles.replace('.',' ') -split "D0"

这给了我一个输出:

Test One File
001 txt
Test Three File
001 txt
Test Two File
001 txt

奇怪的是它的顺序不正确,但我设想我一次只处理 1 个文件,所以这无关紧要。

我想做的是读入一个文件名,忽略“001 txt”部分,使用文件名的第一部分来构建文件移动的目标路径的最后一部分,然后移动文件到该目的地。我可以使用Split-Path -Leafbase,但我不知道它的语法不会给我一个错误,而且我仍然会留下我不想要的部分文件名。

假设我有一个名为One.Two.ThreeD0001 的文件需要转到D:\Files\Onestwosthrees。我希望我的脚本从文件夹中读取文件,然后处理文件One.Two.ThreeD0001.txt,这样剩下的就是“一二三”,将其粘贴在像$SplitFile 这样的变量中,然后将文件移动到文件夹从D:\Files\Onestwosthrees\$SplitFile 之类的文件名构建。

我还想做进一步的解析,但如果我能搞定这部分,我就能找出我需要的子解析。

到目前为止,我查看的一些线索来源是:

https://superuser.com/questions/817955

https://kevinmarquette.github.io/2017-07-31-Powershell-regex-regular-expression/

【问题讨论】:

  • 你能在你的代码示例中添加语法高亮吗?当你把它放进去后给我打电话
  • @Isaac 我不知道如何 ping 你,我点击了你的名字,但没有办法向你发送我可以看到的消息。另外我似乎无法编辑我的帖子,所以我不确定如何在事后添加语法突出显示。我的测试脚本只有 2 行,以 $Testfiles 开头,我不确定论坛为什么将它们放在同一行。与脚本的输出相同,输出应该都在自己的行上。
  • @Squirreljester 你应该可以编辑自己的帖子,但我已经为你做了格式更改。
  • @Nacimota 谢谢!我在帖子上看到了隐藏的小编辑按钮,但是您是如何添加脚本内容的?
  • @Squirreljester 如果您使用四个空格缩进代码,它将被格式化为带有语法着色的代码。对于内联代码块like this,您只需将文本用反引号`like this` 括起来。

标签: regex powershell split


【解决方案1】:

认为你几乎在那里:

cd "C:\Users\users\Downloads\StackTesting"

$testFiles = Get-Childitem -Include *.txt

foreach ( $item in $testfiles ) {
    $directory = ($item.name.replace('.', '') -split "D0")[0]

    ## check if folder exists, if not create
    if (!(Test-Path "C:\Users\user\Downloads\StackTesting\$directory")) 
    { 
       New-Item -Type Directory "C:\Users\users\Downloads\StackTesting\$directory"
    }
    ELSE
    {
        Write-Host "Folder exists"
    }

    ## Move item to folder
   Move-item $item.fullname -Destination "C:\Users\users\Downloads\StackTesting\$directory"

}

这就是我获得您的目录名称的方式:

$directory = ($item.name.replace('.', '') -split "D0")[0]

由于底部的示例没有空格,因此从空格更改为无空格。

【讨论】:

  • 太棒了,谢谢!因此,当您分配拆分的结果时,它会自动忽略拆分后的结果?或者这就是 [0] 的用途,是要保留多少个字符的能指?最下面的例子是我打错了,我需要一个空格,但谢谢你的彻底。 :)
  • 没问题,split 函数将每个split 放入数组的一个元素中,因此[0] 表示数组中的第一个元素。
  • 很抱歉让您久等了回复,我一直很忙。再次感谢!另外,出于好奇,你能把它分成1个以上吗?就像做一个-split "File","D0",然后选择与括号中的数字一起使用,比如[0]是第一部分,[1]是第二部分,[2]是第三部分?我只是想了解它实际上在做什么。
  • 是的,你可以,你可以使用 -split {$_ -eq "D0" -or $_ -eq "File"} 见这里:stackoverflow.com/questions/34915310/…
猜你喜欢
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 2020-04-04
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多