如何使用PowerShell递增文件的副本?

发布于 2025-01-19 17:58:48 字数 1726 浏览 0 评论 0原文

我必须每小时将文件从一个文件夹移动到另一个文件夹。

如果目标文件夹中有文件的副本,我希望它命名为filename_1。在下一个小时内,如果从源再次复制原始文件,则需要它命名为filename_2。如果仍然存在,则FileName_3,然后FileName_4等等。

目前,我只能使用filename_1。问题是,由于我更改文件名并用新的名称替换为覆盖文件名_1。

稍等一下。我在这里做作业。我有一个代码块,可以按名称对文件进行排序,拆分名称,然后将1添加到文件计数器中,但是我没有达到代码的这一部分,因为初始检查(如果存在文件)始终是正确的制作了第一个副本。

任何帮助都将受到赞赏。

代码:

#Sources 
$source = "C:\Users\Desktop\TEST\Test_1\*"
$sourceNameChange = "C:\Users\Desktop\TEST\Test_1"

#Destination 
$destination = "C:\Users\Desktop\TEST\Test_2"

Function MoveFiles{
    Param(
        [string]$src,
        [string]$dest,
        [string]$srcNameChange
    )
   Get-ChildItem -Force -Recurse $src -ErrorAction Stop -ErrorVariable SearchError | ForEach-Object{
     
        $fileNameSrc = $_.Name
        $baseNameSrc = $_.BaseName
        # Check for duplicate files
        $testPath = Test-Path -Path $dest\$baseNameSrc.*
        If( $testPath )
        {
        $fileCounter = 1
        $newName = $_.BaseName + "_"+$fileCounter + $_.Extension
        "$srcNameChange\$fileNameSrc" | Rename-Item -NewName $newName
        }  
        $testPathDest = Test-Path -Path $dest\$baseNameSrc_.*
       If($testPathDest){            
           $sort = Get-Item -Path $dest\* -Filter *$baseNameSrc_* | Sort-Object -Property Name -Descending 
           $destFileName = $sort[1].BaseName
           $destFileCounter = $destFileName.Split("_")[1]
           $destNewName = $_.BaseName + "_"+($destFileCounter+1) + $_.Extension
           "$srcNameChange\$fileNameSrc" | Rename-Item -NewName $destNewName
       }
    }
    Move-Item -Path $src  -Destination $dest -Force
} 
MoveFiles -src $source -dest $destination -srcNameChange $sourceNameChange

I have to move files from one folder to another every hour.

If there is a copy of a file in the destination folder I want it named FileName_1. In the next hour if the original file is copied again from the source want it named FileName_2. If it still exists then FileName_3, then FileName_4 so on and so forth.

Currently, I can get to FileName_1 only. The issue is that since I change the file name and replace it with a new one it overwrites FileName_1.

Hold up a second. I did my homework here. I have a code block that will sort the files by names, split the name, and add 1 to the file counter but I don't reach this part of the code because the initial check (if the file exists) is always true after the first copy is made.

Any help is appreciated.

Code:

#Sources 
$source = "C:\Users\Desktop\TEST\Test_1\*"
$sourceNameChange = "C:\Users\Desktop\TEST\Test_1"

#Destination 
$destination = "C:\Users\Desktop\TEST\Test_2"

Function MoveFiles{
    Param(
        [string]$src,
        [string]$dest,
        [string]$srcNameChange
    )
   Get-ChildItem -Force -Recurse $src -ErrorAction Stop -ErrorVariable SearchError | ForEach-Object{
     
        $fileNameSrc = $_.Name
        $baseNameSrc = $_.BaseName
        # Check for duplicate files
        $testPath = Test-Path -Path $dest\$baseNameSrc.*
        If( $testPath )
        {
        $fileCounter = 1
        $newName = $_.BaseName + "_"+$fileCounter + $_.Extension
        "$srcNameChange\$fileNameSrc" | Rename-Item -NewName $newName
        }  
        $testPathDest = Test-Path -Path $dest\$baseNameSrc_.*
       If($testPathDest){            
           $sort = Get-Item -Path $dest\* -Filter *$baseNameSrc_* | Sort-Object -Property Name -Descending 
           $destFileName = $sort[1].BaseName
           $destFileCounter = $destFileName.Split("_")[1]
           $destNewName = $_.BaseName + "_"+($destFileCounter+1) + $_.Extension
           "$srcNameChange\$fileNameSrc" | Rename-Item -NewName $destNewName
       }
    }
    Move-Item -Path $src  -Destination $dest -Force
} 
MoveFiles -src $source -dest $destination -srcNameChange $sourceNameChange

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热血少△年 2025-01-26 17:58:48

我添加了很多内联注释来帮助您理解函数的逻辑,基本上,您的代码缺少的是一个循环,该循环会增加您正在移动的文件的索引,直到它不存在。

注意,请确保 $destination 不是 $source 中包含的文件夹,否则由于使用 $destination,您最终会得到意外结果代码>-递归。

function Move-Files {
    [cmdletbinding()]
    param(
        [parameter(Mandatory, ValueFromPipeline)]
        [string] $Source,
        [parameter(Mandatory)]
        [string] $Destination
    )
    begin {
        # if destination doesn't exist, create the folder
        if(-not (Test-Path $destination)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
    }
    process {
        # get all the files in `$source` and iterate over them
        Get-ChildItem $source -File -Recurse -Force | ForEach-Object {
            # check if a file with the same name exists in `$destination`
            $thisFile = Join-Path $destination -ChildPath $_.Name
            # if it does exist
            if(Test-Path $thisFile) {
                $i = 0
                # start a loop, using `$i` as index
                do {
                    # increase `$i` on each iteration and get a new name
                    $newName = $_.BaseName + "_" + ++$i + $_.Extension
                    # join the destination path with the new name
                    $thisFile = Join-Path $destination -ChildPath $newName
                    # do this while `$thisFile` exists on `$destination`
                } while(Test-Path $thisFile)
            }
            # if we are here we can assume that either the file didn't exist
            # on `$destination` OR the `do` loop got us a new name
            Move-Item -LiteralPath $_.FullName -Destination $thisFile
        }
    }
}

$source = 'C:\Users\Desktop\TEST\Test_1'
$destination = 'C:\Users\Desktop\TEST\Test_2'
Move-Files -Source $source -Destination $destination

I added lots of inline comments to help you get through the logic of the function, basically, what your code is missing is a loop that increases the index of the file you're moving until it doesn't exist.

Note, be sure that $destination is not a folder contained inside $source or you would end up with unexpected results due to the use of -Recurse.

function Move-Files {
    [cmdletbinding()]
    param(
        [parameter(Mandatory, ValueFromPipeline)]
        [string] $Source,
        [parameter(Mandatory)]
        [string] $Destination
    )
    begin {
        # if destination doesn't exist, create the folder
        if(-not (Test-Path $destination)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
    }
    process {
        # get all the files in `$source` and iterate over them
        Get-ChildItem $source -File -Recurse -Force | ForEach-Object {
            # check if a file with the same name exists in `$destination`
            $thisFile = Join-Path $destination -ChildPath $_.Name
            # if it does exist
            if(Test-Path $thisFile) {
                $i = 0
                # start a loop, using `$i` as index
                do {
                    # increase `$i` on each iteration and get a new name
                    $newName = $_.BaseName + "_" + ++$i + $_.Extension
                    # join the destination path with the new name
                    $thisFile = Join-Path $destination -ChildPath $newName
                    # do this while `$thisFile` exists on `$destination`
                } while(Test-Path $thisFile)
            }
            # if we are here we can assume that either the file didn't exist
            # on `$destination` OR the `do` loop got us a new name
            Move-Item -LiteralPath $_.FullName -Destination $thisFile
        }
    }
}

$source = 'C:\Users\Desktop\TEST\Test_1'
$destination = 'C:\Users\Desktop\TEST\Test_2'
Move-Files -Source $source -Destination $destination
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文