简体   繁体   English

根据Powershell中的文件名将文件移动到新位置

[英]moving files to new locations based on file name in powershell

I have a folder (no sub-folders) full of thousands of files of differing formats (pdf,xls,jpeg, etc). 我有一个文件夹(没有子文件夹),其中充满了成千上万种格式不同的文件(pdf,xls,jpeg等)。 The files don't have a common naming structure, with the only pattern relating them being that somewhere within the file name there are the letters PN immediately followed by a 6 digit number. 文件没有通用的命名结构,与文件相关的唯一模式是在文件名中的某个地方,字母PN紧跟着6位数字。 The PNxxxxxx code may occur at any point in the file name either at the start, end, between spaces or other characters. PNxxxxxx代码可能出现在文件名中的任何位置,无论是在开头,结尾,空格还是其他字符之间。

Multiple files can share the same PN code, for example, a pdf, xls and jpeg may all have PN854678 in their title. 多个文件可以共享相同的PN代码,例如,pdf,xls和jpeg的标题中都可能带有PN854678。

I have written a script for powershell trying to move all the files to a new location where they will be placed into a folder (which may or may not exist yet) along with any other files that may share the same code. 我已经为powershell编写了一个脚本,试图将所有文件与可能共享相同代码的其他文件一起移动到新位置,在该位置将它们放置到一个文件夹中(可能存在或可能不存在)。 The folder is to have PN followed by the correct 6 digits as its name. 该文件夹的名称后面应有PN,后跟正确的6位数字。

When I try to run my script, nothing happens I get no errors or anything. 当我尝试运行脚本时,什么也没有发生,但我没有收到任何错误或任何提示。 The code executes, I think, and the source and target folders are unchanged. 我认为代码会执行,并且源文件夹和目标文件夹不变。 Just to confirm, I have used set-executionpolicy remotesigned and also tried running the script using cmd.exe. 只是为了确认,我使用了set-executionpolicy remotesigned ,还尝试使用cmd.exe运行脚本。

Here is the code, keep in mind that this my first attempt at using powershell and i'm new to scripting in general so I apologize if I have made any silly mistakes. 这是代码,请记住,这是我第一次尝试使用Powershell,而且我一般都不熟悉脚本编写,因此,如果我犯了任何愚蠢的错误,我深表歉意。

# Set source directory to working copy
$sourceFolder = "C:\Location A"

#Set target directory where the organized folders will be created
$targetFolder = "C:\Location B"

$fileList = Get-Childitem -Path $sourceFolder
foreach($file in $fileList)
{
    if($file.Name -eq "*PN[500000-999999]*") #Numbers are only in range from 500000 to 999999
    {

        #Extract relevant part of $file.Name using regex pattern -match 
        #and store as [string]$folderName

    $pattern = 'PN\d{6}'

        if($file.Name -match $pattern)
        {        
            [string]$folderName = $matches[0]        
        }


    #Now move file to appropriate folder

    #Check if a folder already exists with the name currently contained in $folderName
        if(Test-Path C:\Location B\$folderName) 
        {
            #Folder already exists, move $file to the folder given by $folderName
            Move-Item C:\Location A\$file C:\Location B\$folderName                  
        }
            else
        {
            #Relevant folder does not yet exist. Create folder and move $file to created folder
            New-Item C:\Location B\$folderName -type directory
            Move-Item C:\Location A\$file C:\Location B\$folderName
        }

    }
} 

Do you files exists all in one folder or in a series of subfolders? 文件是否全部存在于一个文件夹或一系列子文件夹中? You don't mention it but keep in mind you would need -recurse on Get-Childitem to get results from subfolders. 你不提,但要记住,你需要-recurseGet-Childitem从子文件夹中得到结果。 The source of your issue is this clause $file.Name -eq "*PN[500000-999999]*" . 问题的根源是此子句$file.Name -eq "*PN[500000-999999]*" -eq was not meant to handle wlidcards. -eq并不是要处理Wlidcard。 I would suggest this simple alternate 我建议这个简单的选择

$file.Name -match 'PN\d{6}'

However you specified that the number needs to be in a certain range. 但是,您指定的数字必须在一定范围内。 Lets just give everything a little update. 让我们对所有内容进行一些更新。

# Set source directory to working copy
$sourceFolder = "C:\Location A"

#Set target directory where the organized folders will be created
$targetFolder = "C:\Location B"

foreach($file in $fileList)
{
    # Find a file with a valid PN Number
    If($file.Name -match 'PN[5-9]\d{5}'){
        # Capture the match for simplicity sake
        $folderName = $matches[0]

        #Check if a folder already exists with the name currently contained in $folderName
        if(!(Test-Path "C:\Location B\$folderName")){New-Item "C:\Location B\$folderName" -type directory} 

        #Folder already exists, move $file to the folder given by $folderName
        Move-Item "C:\Location A\$file" "C:\Location B\$folderName"                  
    }

}
  1. Don't forget to quote your strings. 不要忘了引用您的字符串。 You can put the variables inside double quoted strings and they will expand appropriately. 您可以将变量放在双引号引起来的字符串中,它们会适当扩展。
  2. $file.Name -match 'PN([5-9]\\d{5})' What that does is find files that contain PN followed by any number between 5 to 9 then followed by 5 more digits. $file.Name -match 'PN([5-9]\\d{5})'作用是查找包含PN的文件,后跟5到9之间的任何数字,再加上5个数字。 That should take care of the 500000-999999 criteria. 那应该照顾500000-999999标准。
  3. Also you are going to move the file anyway. 另外,您还是要移动文件。 No sense having the line twice with Move-Item . Move-Item两次行没有意义。 Instead just do a check on the path. 相反,只需检查路径即可。 If its not (!) there then create the folder. 如果不是(!),则创建文件夹。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM