如何最有效地移动

如何最有效地移动

本文介绍了如何最有效地移动、重命名文件和记录此操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 CSV 列表(实际上有 1000 行):

针,代码123456,AB121212,BB33333333,CVV

而且我有一个包含 PDF 文件的目录 (C:\old_files)(实际上是 1000 个):

dsadsadsa.343222.dsads23213jkjl.saddsa.pdfdsadsadsa.123456.dsads23213jkjl.saddsa.pdfdsadsadsa.111111.dsads23213jkjl.saddsa.pdfdsadsadsa.33333333.dsads23213jkjl.saddsa.pdfdsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

对于 CSV 中的每一根针:

  • 我必须查看是否有包含该针的 PDF(可能有 0 个或多个匹配项)
  • 如果有比赛,我必须

    1. 将文件复制到一个单独的文件夹 (D:\new_files)
    2. 通过在名称前添加相应的代码来重命名复制的文件
    3. 在日志中写入一个条目.

例如,我有 123456 的匹配项和 33333333 的 2 个匹配项,因此我必须将这些文件的副本移动到 D:\new_files 并将它们重命名为:

AB.dsadsadsa.123456.dsads23213jkjl.saddsa.pdfCVV.dsadsadsa.33333333.dsads23213jkjl.saddsa.pdfCVV.dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

日志文件看起来像(格式 needle,code,oldfilepath,newfilepath):

123456,AB,C:\old_files\dsadsadsa.123456.dsads23213jkjl.saddsa.pdf,D:\new_files\AB.dsadsadsa.123456.dsads23213jkjl.saddsa.pdf33333333,CVV,C:\old_files\dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf,D:\new_files\CVV.dsadsadsa.33333333.dsadsads23213jkjl.saddsa.pdf33333333,CVV,C:\old_files\dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf,D:\new_files\CVV.dsadsadsa.33333333.fsdgdsfdsfdsfdsfds

重要的是,我只循环遍历目录中的文件一次,因为在 ForEach 循环中为每个 needle 迭代所有文件花费的时间太长.多亏了这个论坛,我首先建立了一个哈希表:

$pairs = @{}导入-CSV .\data.csv |ForEach-Object { $pairs[$_.needle] = $_.code+"."}Get-ChildItem "C:\old_files" |Rename-Item -NewName { "D:\new_files\" + $pairs[$_.Name.Split('.')[1]] + $_.Name }

我的第一个问题是:我无法将文件移动到新文件夹中.

Q1 如何正确地将文件从 C:\old_files 复制到 D:\new_files 并重命名?

我的第二个问题:我不明白如何在上面的代码中添加代码.

Q2 如何为每个匹配项创建日志文件(因此:复制和重命名文件)?

解决方案

在复制匹配文件之前,您需要实际检查是否有匹配项.

Get-ChildItem "C:\old_files" |ForEach-Object {$n = ($_.Name -split '.')[1]如果($pair[$n]){$oldname = $_.FullName$newname = Join-Path 'C:\new_files' ($pair[$n] + $_.Name)复制项目 $oldname $newname}}

复制操作后做日志记录:

Copy-Item $oldname $newname如果($?){# 在此记录成功信息} 别的 {# 在这里记录错误信息}

I have the following CSV list (in reality 1000s of lines):

needle,code
123456,AB
121212,BB
33333333,CVV

And I have a directory (C:\old_files) containing PDF files (again, 1000s in reality):

dsadsadsa.343222.dsads23213jkjl.saddsa.pdf
dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
dsadsadsa.111111.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

For each needle in the CSV:

  • I have to see if there is a PDF containing that needle (there might be 0 or more matches)
  • If there is a match, I have to

    1. make a copy of the file into a separate folder (D:\new_files)
    2. rename the copied file by prepending the respective code to the name
    3. write an entry into the log.

For the example, I have a match for 123456 and 2 for 33333333, so I have to move a copy of these files into D:\new_files and rename them into:

AB.dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
CVV.dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
CVV.dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

The logfile would look like (format needle,code,oldfilepath,newfilepath):

123456,AB,C:\old_files\dsadsadsa.123456.dsads23213jkjl.saddsa.pdf,D:\new_files\AB.dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
33333333,CVV,C:\old_files\dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf,D:\new_files\CVV.dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
33333333,CVV,C:\old_files\dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf,D:\new_files\CVV.dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

It is important that I only loop over the files in the directory once, because iterating through all files in a ForEach loop for each needle takes way too long. So with thanks to this forum I'm building a hashtable first:

$pairs = @{}
Import-CSV .\data.csv | ForEach-Object { $pairs[$_.needle] = $_.code+"." }

Get-ChildItem "C:\old_files" | Rename-Item -NewName { "D:\new_files\" + $pairs[$_.Name.Split('.')[1]] + $_.Name }

My first problem here: I am unable to move the file into the new folder.

Q1 How do I properly copy a file from C:\old_files into D:\new_files and rename it?

My second problem: I don't understand how I can add code to the above code.

Q2 How can I create the logfile for each match (and therefore: copied and renamed file)?

解决方案

You need to actually check if you have a match before copying the matching file.

Get-ChildItem "C:\old_files" | ForEach-Object {
  $n = ($_.Name -split '.')[1]
  if ($pair[$n]) {
    $oldname = $_.FullName
    $newname = Join-Path 'C:\new_files' ($pair[$n] + $_.Name)
    Copy-Item $oldname $newname
  }
}

Do the logging after the copy operation:

Copy-Item $oldname $newname
if ($?) {
  # log success information here
} else {
  # log error information here
}

这篇关于如何最有效地移动、重命名文件和记录此操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 21:07