我想要半自动地将 DCIM 文件从我的 iPhone 复制并分类到我的电脑上,将“相关”的相机图像放在一起并与屏幕截图、下载的 jpeg、gif、mpeg、png 等分开。
我的 iPhone 上有一堆下载的图片(来自 Pinterest、Tumblr 等)。我还用 iPhone 相机拍摄了一堆相关的 jpg/mp4 图片,这些图片成对拍摄,按文件名顺序一个接一个。显然,iPhone 相机会为每张照片录制 jpeg 图像和多帧 mp4 影片。下载的图像只是单个 jpeg、gif、mp4 等。
我希望脚本驻留在本地计算机上,并在 iPhone 安装后手动运行。
iPhone 图像路径为:'mtp://Scottc 的 iPhone/内部存储/DCIM/291APPLE', 'mtp://Scottc 的 iPhone/内部存储/DCIM/292APPLE', 'mtp://Scottc 的 iPhone/内部存储/DCIM/293APPLE',ETC。
我无法控制子目录名称(例如291苹果,292苹果,293苹果等,但它们总是以(看似随机的)3 位数字开头,并以“APPLE”结尾。可以有一个或十个。这取决于 iOS 和文件数量。子目录是只读的,但文件本身是可读写的,因此可以稍后删除。
因此,我需要递归处理所有文件,直到'mtp://Scottc 的 iPhone/内部存储/DCIM/'。
iPhone 上每个子文件夹中的目录列表如下所示:
*image001.jpg* <-- downloaded *image002.jpg* <-- downloaded *image003.jpg* <-- camera image a *image004.mp4* <-- camera image b *image005.jpg* <-- downloaded *image006.jpg* <-- downloaded *image007.jpg* <-- downloaded *image008.jpg* <-- downloaded *image009.jpg* <-- camera image a *image010.mp4* <-- camera image b *image011.jpg* <-- downloaded
因此文件 003 和 004 是相关的,文件 009 和 010 也是相关的。Scottc 的 iPhone/DCIM/* 中的所有文件都有唯一的名称。
我只想将相关图像复制到目录 A,将剩余图像(下载,可以是任何类型 jpg、gif、mp4 等)复制到目录 B。
有人能帮我解释一下实现这个功能的 Powershell 逻辑和代码吗?我真的不知道该怎么做。也许有更好的方法或有人已经写好的实用程序?如果是这样,我一直找不到,而且一次处理数百张图像真的很繁琐。这似乎是 Powershell 的完美应用程序。
我思考我需要循环遍历文件,识别第一个 *.mp4 文件,将文件名放入变量中,将 *.mp4 文件复制到目录 A,然后从变量中减去值 1 以按字母顺序匹配前面的相关 *.jpg 文件名并将其复制到目录 A。
冲洗并重复。
然后将剩余的不相关文件(任何类型)复制到目录 B。
因此,最终我得到了以下目录结构:
On the iPhone:
(leave the original files as is)
Directory A
image003.jpg <-- camera image a
image004.mp4 <-- camera image b
image009.jpg <-- camera image a
image010.mp4 <-- camera image b
Directory B
image001.jpg <-- downloaded
image002.jpg <-- downloaded
image005.jpg <-- downloaded
image006.jpg <-- downloaded
image007.jpg <-- downloaded
image008.jpg <-- downloaded
image011.jpg <-- downloaded
最后,询问用户是否要删除 iPhone 原始文件(我想我可以处理这部分)但不删除 iPhone 目录(上面提到的权限问题……iOS 会处理目录结构)。
我认为一个问题就是,下载的以 *.mp4 结尾的电影将与之前下载的不相关的 *.jpg 文件匹配。除非有人有巧妙的方法来处理这个问题。我可以忍受这个小小的限制。我注意到相关的 jpg/mp4 文件具有相同的 hh:ss 时间戳,如果这有帮助的话。下载的图像/电影/gif 从来都不匹配时间。也许匹配时间戳更容易?也不知道如何实现。
我真正感到困惑的是文件名变量的处理,数学-1处理文件名时的逻辑以及如何处理剩余的文件名(在数组中,还是通过迭代?)。复制、移动、名称匹配等。我想我可以通过反复试验来解决——但请随意详细说明。有些人可以即时完成的事情需要我几个小时,经常以失败和沮丧告终 :-(
有人能帮忙吗?我的 Powershell 技能只达到第 3 章左右,所以我真的很挣扎。
答案1
这有点晚了,但我针对 iPhone 的特定子文件夹对这个脚本进行了一些调整: https://blog.daiyanyingyu.uk/2018/03/20/powershell-mtp/
与原始脚本不同的是最后一部分,现在循环遍历DCIM
文件夹中的子文件夹。然后,此脚本移动将所有文件复制到目标。它没有直接回答您的问题,但至少解决了 MTP 驱动器部分。更改:
$items = @( $folder.GetFolder.items() | where { $_.Name -match $filter } )
到
$subfolders = $folder.GetFolder.items()
foreach ($subfolder in $subfolders) {
$items = @( $subfolder.GetFolder.items() | where { $_.Name -match $filter } )
}
当然最后还会有一个额外的。
更改后的使用示例:
./mptcopy.ps1 -phoneName 'Apple iPhone' -sourceFolder '\Internal Storage\DCIM' -targetFolder 'C:\pics' -filter '(.jpg)|(.jpeg)|(.png)|(.gif)|(.bmp)'
答案2
尝试一下,并让我们知道它是否有效:
编辑:我忘了搜索每个目录。现在应该修复了。
$directoryA = "%userprofile%\Pictures\Directory A"
$directoryB = "%userprofile%\Pictures\Directory B"
$items = Get-ChildItem ".\\image*" -Recurse | ForEach-Object { if (!($_.PSIsContainer)) { $_}}
$i = 0
$mp4s = @()
$associatedImgs = @()
ForEach($item in $items) {
If(($items[$items.IndexOf($item)].Extension).Equals(".mp4")) {
$mp4s += $i
$associatedImgs += $i - 1
}
$i += 1
}
ForEach($mp4 in $mp4s) {
Copy-Item -Path $items[$mp4].FullName -Destination $directoryA -Force -PassThru -Verbose
Copy-Item -Path $items[$mp4 - 1].FullName -Destination $directoryA -Force -PassThru -Verbose
}
ForEach($item in $items) {
If($mp4s.Contains($items.IndexOf($item))){
} ElseIf($associatedImgs.Contains($items.IndexOf($item))) {
} Else {
Copy-Item -Path $items[$item].FullName -Destination $directoryB -Force -PassThru -Verbose
}
}
答案3
.mp4
如果/对的创建时间.jpg
可靠,
您可以尝试根据此属性对文件进行分组:
Get-ChildItem -Recurse -include '*.htm','*.ps1'|
Group-Object Creationtime|
ForEach-Object {If($_.Group.Count -eq 2){$_.Group.Fullname;"---"}}
这将仅输出两个匹配的时间对以供检查。