简体   繁体   English

使用Powershell将文件夹结构中的文件复制到其各自的子文件夹

[英]Copy files in a folder structure to their respective sub-folder with Powershell

I want to move the file "file_to_move.txt"in each folder to their respective "done"-folder. 我想将每个文件夹中的文件“ file_to_move.txt”移动到它们各自的“完成”文件夹中。

so the file_to_move.txt in C:\\Temp\\test\\folder1 is moved to C:\\Temp\\test\\folder1\\done and file_to_move.txt in C:\\Temp\\test\\folder2 is moved to C:\\Temp\\test\\folder2\\done 所以file_to_move.txtC:\\ TEMP \\测试\\ folder1中移动到C:\\ TEMP \\测试\\ folder1中\\完成 ,用C file_to_move.txt:\\ TEMP \\测试\\文件夹2移动到C:\\ TEMP \\测试\\ folder2 \\ done

...and so on, preferably with a %date%_%time% added to the file-name. ...依此类推,最好在文件名中添加%date%_%time%。

if a folder (like folder4 in the example below) does not have a file_to_move.txt, the script should just ignore it and move on. 如果文件夹(如下面的示例中的folder4)没有file_to_move.txt,则脚本应忽略它并继续前进。

folder structure example: 文件夹结构示例:

  • C:\\Temp\\test\\DONE C:\\ Temp \\ test \\ DONE
  • C:\\Temp\\test\\folder1 C:\\ Temp \\ test \\ folder1
  • C:\\Temp\\test\\folder1\\done C:\\ Temp \\ test \\ folder1 \\ done
  • C:\\Temp\\test\\folder1\\some_other_folder C:\\ Temp \\ test \\ folder1 \\ some_other_folder
  • C:\\Temp\\test\\folder1\\some_other_file.txt C:\\ Temp \\ test \\ folder1 \\ some_other_file.txt
  • C:\\Temp\\test\\folder1\\file_to_move.txt C:\\ Temp \\ test \\ folder1 \\ file_to_move.txt
  • C:\\Temp\\test\\folder2 C:\\ Temp \\ test \\ folder2
  • C:\\Temp\\test\\folder2\\done C:\\ Temp \\ test \\ folder2 \\ done
  • C:\\Temp\\test\\folder2\\some_other_folder C:\\ Temp \\ test \\ folder2 \\ some_other_folder
  • C:\\Temp\\test\\folder2\\some_other_file.txt C:\\ Temp \\ test \\ folder2 \\ some_other_file.txt
  • C:\\Temp\\test\\folder2\\file_to_move.txt C:\\ Temp \\ test \\ folder2 \\ file_to_move.txt
  • C:\\Temp\\test\\folder3 C:\\ Temp \\ test \\ folder3
  • C:\\Temp\\test\\folder3\\done C:\\ Temp \\ test \\ folder3 \\ done
  • C:\\Temp\\test\\folder3\\some_other_folder C:\\ Temp \\ test \\ folder3 \\ some_other_folder
  • C:\\Temp\\test\\folder3\\some_other_file.txt C:\\ Temp \\ test \\ folder3 \\ some_other_file.txt
  • C:\\Temp\\test\\folder3\\file_to_move.txt C:\\ Temp \\ test \\ folder3 \\ file_to_move.txt
  • C:\\Temp\\test\\folder4 C:\\ Temp \\ test \\ folder4
  • C:\\Temp\\test\\folder4\\done C:\\ Temp \\ test \\ folder4 \\ done
  • C:\\Temp\\test\\folder4\\some_other_folder C:\\ Temp \\ test \\ folder4 \\ some_other_folder
  • C:\\Temp\\test\\folder4\\some_other_file.txt C:\\ Temp \\ test \\ folder4 \\ some_other_file.txt

I have experimented with a Powershell script even if I'm not very good at it and I dont know it can be done in a standard batch-script. 即使我不太擅长于Powershell脚本,我也进行了试验,但我不知道它可以用标准的批处理脚本来完成。 I have tried this so far: 到目前为止,我已经尝试过了:

In a batch-script: 在批处理脚本中:

SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%bin\movescript.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'"

in the movescript.ps1: 在movescript.ps1中:

Move-Item C:\Temp\test\*\file_to_move.txt C:\Temp\test\*\done\file_to_move_$(get-date -f yyyyMMdd_HHmmss).txt

But this is not working. 但这是行不通的。 I guess it's not precise enough to work. 我猜这还不够精确。

As a bonus, can the whole thing be done within the basic script or must we use the external .PS1-file? 另外,可以在基本脚本内完成全部操作,还是必须使用外部.PS1-文件?

You can use the Get-ChildItem cmdlet with a filter to retrieve all file_to_move.txt files recursively from a path. 您可以将Get-ChildItem cmdlet与过滤器一起使用,以从路径递归检索所有file_to_move.txt文件。 Use the Foreach-Object (alias foreach) to iterate over them and combine the new path using the Join-Path cmdlet. 使用Foreach-Object (别名foreach)对它们进行迭代,并使用Join-Path cmdlet合并新路径。 To Copy the Item, you can use the Copy-Item cmdlet: 若要复制项目,可以使用Copy-Item cmdlet:

$itemsToCopy = Get-ChildItem -Path c:\Temp\Test -Filter file_to_move.txt -Recurse 
$itemsToCopy | foreach {
    $newPath = Join-Path $_.DirectoryName 'done'
    New-Item -Path $newPath -ItemType directory -Force | out-null
        $_ | Copy-Item -Destination $newPath
}

If you want to add a Timestamp, you could use the Get-Date cmdlet and invoke the ToString method with your desired format on it, example: 如果要添加时间戳,则可以使用Get-Date cmdlet并以所需的格式调用ToString方法,例如:

(Get-Date).ToString("yyyy-dd-M_HH-mm-ss")

Output: 输出:

2016-05-4_15-06-02

You can now concat the filenames using a format string and the $_.Basename and $_.Extension property within your foreach loop. 现在,您可以在foreach循环中使用格式字符串以及$_.Basename$_.Extension $_.Basename属性来连接文件名。 I will leave this as an exercise to you. 我将把它作为练习留给您。

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

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