【问题标题】:How do I amend this PS script to move files into the correct folders?如何修改此 PS 脚本以将文件移动到正确的文件夹中?
【发布时间】:2020-01-27 11:58:12
【问题描述】:

我目前的 PS 脚本是:

$loc = "C:\Users\USER\Desktop\New folder1"
$files = Get-ChildItem -Path $loc
for ($i=0; $i -lt $files.Count; $i++) 
{
$outfile = $files[$i].FullName
$filename = Split-Path -Path $outfile -Leaf -Resolve
$Year = $filename -replace "Status_\d{0}(\d{4})[\d_]*.txt",'$1'
$Month = $filename -replace "Status_\d{4}(\d{2})[\d_]*.txt",'$1'
$folderYYYY = Join-Path -Path  $loc -ChildPath $Year
$folderMM = Join-Path -Path $folderYYYY -ChildPath $Month
$ExistsYYYY = Test-Path $folderYYYY
$ExistsMM = Test-Path $folderMM
If (!$ExistsYYYY) 
{ 
    New-Item -Type directory -Path $folderYYYY
}
If (!$ExistsMM)
{ 
    New-Item -Type directory -Path $folderMM
} 
Move-Item $outfile $folderMM
}

该脚本应该将当前位于 $loc 目录中的文件移动到 YYYY-MM 子文件夹中。如果 YYYY 或 MM 子文件夹不存在,则会创建它。如果子文件夹路径已经存在,则将文件移动到该子文件夹中。

文件名始终采用以下格式:

Status_20180215_074559.txt

所以对于上面的文件,YYYY 会映射到 2018,MM 会映射到 02

通过测试脚本 - 如果 YYYY 子文件夹不存在,则脚本运行良好。 如果 YYYY 子文件夹已经存在,那么我最终会得到脚本创建的以下路径:

C:\Users\USER\Desktop\New folder1\2018
C:\Users\USER\Desktop\New folder1\2018\02
C:\Users\USER\Desktop\New folder1\2018\2018

文件被上面的脚本移动到下面的路径中:

C:\Users\USER\Desktop\New folder1\2018\02

我也收到以下错误:

Move-Item : Access to the path 'C:\Users\USER\Desktop\New folder1\2018' is denied. 
At line:14 char:10 
+ Move-Item <<<<  $outfile $folder 
+ CategoryInfo : WriteError: (C:\Users\USER...ew folder1\2018:DirectoryInfo) [Move-Item], IOException 
+ FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand 

任何停止创建以下路径的方法:

C:\Users\USER\Desktop\New folder1\2018\2018

另外,如何解决抛出的错误?

非常感谢

编辑:尝试了@Theo 脚本,但出现以下问题:

然后我删除了所有的 cmets 和空行,认为这可能会在某处引起一些问题,但随后出现以下错误:

所以,在其他人的帮助下,我的脚本的问题是 $files 行 - 它应该只查找文件:

$files = Get-ChildItem -Path "$loc\*.txt"

另外,@Theo 提供的修改后的 PS 脚本非常有用,因为我有 PS 版本 2

【问题讨论】:

  • 你的正则表达式似乎到处都是。例如,您将.. 匹配,而它应该是\. 以匹配文字点,并且当它应该是CSV 时检查txt。您可能只是在运行不同的脚本,因此很难提供帮助。
  • 嗨@Seth这是我的确切脚本,唯一的区别是位置参​​数有我的实际用户名,而不是用户。才发现,这个文件其实是个txt文件,我错误地把它标记为.csv
  • 你指的是@Theo提供的脚本吗?如果是这样,我删除了所有的 cmets 和空行,但它仍然没有工作

标签: powershell


【解决方案1】:

您的代码非常混乱且过于复杂。无需单独检查文件目标的每一部分,因为New-Item cmdlet 可以一次性创建完整路径。

此外,使用ForEach-Object 传递Get-Childitem 的结果并在该循环中使用$_ 自动变量要简单得多。

类似这样的:

$loc = "C:\Users\USER\Desktop\New folder1"

Get-ChildItem -Path $loc -File -Filter 'Status_*' |        # get a list of files with names starting with 'Status_'
    Where-Object { $_.BaseName -match '_\d{8}_\d{6}$' } |  # filter files that have the '_date_time' format 
    ForEach-Object {                                       # loop through
        # join the year and month as partial destination path
        $targetpath  = '{0}\{1}' -f $_.Name.Substring(7,4), $_.Name.Substring(11,2)
        # ceate the full destination path for the file
        $destination = Join-Path -Path $loc -ChildPath $targetpath

        # check if the path exists and if not, create it
        if (!(Test-Path -Path $destination -PathType Container)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
        # now move the file to the destination path
        $_ | Move-Item -Destination $destination
    }


编辑

您似乎使用的是 PowerShell 2.0 版,然后 -File 开关不存在。对于该版本,您需要像这样调整代码:

$loc = "C:\Users\USER\Desktop\New folder1"

Get-ChildItem -Path $loc -Filter 'Status_*' |
    Where-Object { !$_.PSIsContainer -and  $_.BaseName -match '_\d{8}_\d{6}$' } | 
    ForEach-Object {
        # join the year and month as partial destination path
        $targetpath  = '{0}\{1}' -f $_.Name.Substring(7,4), $_.Name.Substring(11,2)
        # ceate the full destination path for the file
        $destination = Join-Path -Path $loc -ChildPath $targetpath

        # check if the path exists and if not, create it
        if (!(Test-Path -Path $destination -PathType Container)) {
            $null = New-Item -Path $destination -ItemType Directory
        }
        # now move the file to the destination path
        $_ | Move-Item -Destination $destination
    }

【讨论】:

  • 嗨@Theo,我已经尝试过了,但管道字符和文件参数出现问题,请参阅主帖
  • @Naz \\\1。你是怎么复制/粘贴这个的?在图像中,我看到我的代码使用直引号的地方有花引号。只需复制并直接粘贴到 PowerShell ISE 编辑器中。 \\\2.此外,您似乎使用的是旧版本的 PowerShell (2.0),而 -File 开关未知。为此,我编辑了答案。
  • 啊哈我明白了,如果我复制引号字符,它们会在 PS 中粘贴为卷曲?不过现在,有了修改后的 PS,它仍然可以工作,所以我想没关系。我也最好升级我的PS版本。感谢您的帮助
【解决方案2】:

简单的老式 bash 方式,例如:

p:\DANE\telefony\Marcin\Archiwum>..\..\move-archive.bat
move IMG-20220119-WA0000.jpg 2022\2022-01\
move IMG-20220119-WA0001.jpg 2022\2022-01\

move-archive.bat 的代码

@echo off
rem not %var% but !var! give us access to internal loop variable value with enabledelayedexpansion.
setlocal enabledelayedexpansion
rem Run by scheduler script in p:\dane\telefony\marcin\move-archive.bat
rem p:
rem cd p:\dane\telefony\marcin\archiwum
FOR %%V IN (*.*) DO (
rem echo "****** %%V *********"
SET filedate=%%~tV
rem echo !filedate!
SET fileyear=!filedate:~6,4!
rem echo !fileyear!
SET filemonth=!filedate:~3,2!
rem echo !filemonth!
rem create directory as yyyy\yyyy-MM
mkdir !fileyear!\!fileyear!-!filemonth! 2>nul
echo move %%V !fileyear!\!fileyear!-!filemonth!\
move %%V !fileyear!\!fileyear!-!filemonth!\ >nul
)

【讨论】:

    猜你喜欢
    • 2021-10-15
    • 2015-06-14
    • 2013-06-07
    • 2018-12-27
    • 2014-08-05
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多