问题描述
我有以下 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 个或多个匹配项)
- 如果有比赛,我必须
- 将文件复制到一个单独的文件夹 (
D:\new_files
) - 通过在名称前添加相应的代码来重命名复制的文件
- 在日志中写入一个条目.
- 将文件复制到一个单独的文件夹 (
例如,我有 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,CVVAnd 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.pdfFor 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
- make a copy of the file into a separate folder (
D:\new_files
) - rename the copied file by prepending the respective code to the name
- write an entry into the log.
- make a copy of the file into a separate folder (
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
}
这篇关于如何最有效地移动、重命名文件和记录此操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!