列出一个文件夹结构中不在另一个文件夹结构中的文件

3

我刚拿到一部新手机,暂时将旧手机上的文件复制到了我的电脑C:\OldPhone\。

在我的电脑上有所有的照片,它们位于D:\Photos下的各个文件夹中。

我需要一些代码来列出所有在C:\OldPhone\下但是不在D:\Photos\下的.jpg文件。

理解我的意思了吗?强调一下,文件夹结构并不相同,我不介意文件在哪里,只要它在那里就可以。首先进行文件名比较即可,添加大小选项将是一个额外的奖励!

CMD、VBS或powershell都可以,但任何Visual Studio能够处理的东西也可以。


你已经尝试过什么了吗? - GOTO 0
5个回答

3

试试这个:

for /r "D:\Photos" %%a in (*.jpg) do set "$%%~na=1"
for %%a in (C:\OldPhone\*.jpg) do if not defined $%%~na echo %%~a not in d:\photos

cmd有类似awk的关联数组。但是,如果文件名中包含=字符,则无法使用。


1
批处理/CMD 没有 关联数组。 - Ansgar Wiechers
2
@AnsgarWiechers 在 Bash 之前就有了这些关联数组,最近才得到了支持。 - Endoro
1
CMD没有关联数组。最接近的你可以拥有的是Rob van der Woude在这里描述的仿真方法(http://www.robvanderwoude.com/battech_array.php)。 - Ansgar Wiechers
1
请查看Wikipedia文章。在批处理/CMD中,您拥有的不是单个数据结构,而是一堆具有奇怪名称的单独变量。没有添加或删除操作,没有查找,也没有迭代器。 - Ansgar Wiechers
1
@Aacini 请给自己找一本好的关于数据结构的书并阅读。仅仅因为你可以让某些东西看起来有点像鸭子,并不意味着它就是鸭子。 - Ansgar Wiechers
显示剩余6条评论

2
这应该可以在PowerShell中完成。
$ht=@{}  # initialize empty hashtable
dir C:\OldPhone\*.jpg -r -file | Foreach {$ht["$($_.Name):$($_.Length)"] = $_.FullName}
dir D:\Photos\*.jpg -r file | Foreach {$ht.Remove("$($_.Name):$($_.Length)")}
$ht  # dump remaining hashtable contents

这还考虑了文件的大小,以防您有多个具有相同名称的文件。理想情况下,为确保它们相同,应将MD5文件哈希包括在每个文件的$ht键中,而不是文件长度作为哈希表的一部分。请注意,-file参数是PowerShell V3中的新功能。除非您有一些文件夹的名称中包含.jpg,否则您可能不需要它。


Keith的回答也很好,虽然我没有尝试过。对我来说,cmd解决方案更简单一些。 - FrinkTheBrave

0
For /R %%i In (newfiles\*.jpg) Do Call :Check "%%~fi"
GoTo :EOF

:Check
For /R %%i In (existingfiles\*.jpg) Do If /I "%%~nxi"=="%~nx1" GoTo :Found
Echo File %1 doesn't already exist!
GoTo :EOF

:Found
Echo File %1 already exists!
GoTo :EOF

0

这是我根据Endoro的答案得出的结果。我真的应该将文件夹位置放入变量中,但现在它可以工作了,所以这就是我需要的全部!我还应该将setlocal ... endlocal行放入子例程中。 现在看起来,OLDFOLDER也是一个愚蠢的名称。这是糟糕的编码!

它会复制任何缺失的.jpg或.mp4文件到一个文件夹中,以便更容易地复制。

echo off
set OLDFOLDER=C:\OldPhone
cls
echo Checking for files in %OLDFOLDER% which aren't in D:\Pictures
del /f /q "D:\Documents\MissingFiles\*"
setlocal
for /r "D:\Photos" %%a in (*.jpg) do set "$%%~nxa=1"
for /r "%OLDFOLDER%" %%a in (*.jpg) do if not defined $%%~nxa copy "%%~a" "D:\Documents\MissingFiles\"
endlocal
setlocal
for /r "D:\Photos" %%a in (*.mp4) do set "$%%~nxa=1"
for /r "%OLDFOLDER%" %%a in (*.mp4) do if not defined $%%~nxa copy "%%~a" "D:\Documents\MissingFiles\"
endlocal
if exist "D:\Documents\MissingFiles\*.*p*" (
  echo Files missing from D:\Photos copied to D:\Documents\MissingFiles\
) else (
  echo There are no files in %OLDFOLDER% which aren't in D:\Photos
)
pause

-1
使用fciv(和grep):
fciv .\old -r | grep jpg > old.txt
fciv .\new -r | grep jpg > new.txt

获取

old.txt

6d5f1279d4deccbaeef5d074b13ed2f4 .\old\b\100_1608.jpg
d95e29e2c0172dea438b12c418b09fd3 .\old\b\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\old\b\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\old\b\100_1600.jpg
26ff43419c4f30764fb015f6d7c869c1 .\old\b\100_1609.jpg
d95e29e2c0172dea438b12c418b09fd3 .\old\a\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\old\a\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\old\a\100_1600.jpg

new.txt

545b2121a3af2a8e5aa3c5946b450e87 .\new\c\100_1605.jpg
02a1638739302f3c17253beaa3fe9c1b .\new\c\100_1603.jpg
d95e29e2c0172dea438b12c418b09fd3 .\new\c\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\new\c\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\new\a\100_1600.jpg

使用 schema.ini 文件:

[old.txt]
Format=Delimited( )
ColNameHeader=False
Col1=MD5 CHAR
Col2=PATH CHAR

[new.txt]
Format=Delimited( )
ColNameHeader=False
Col1=MD5 CHAR
Col2=PATH CHAR

以及VBScript:

Option Explicit

Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")

Dim oDb : Set oDb = CreateObject("ADODB.Connection")
Dim sCS : sCS     = Join(Array(_
     "Provider=MSDASQL" _
   , "Driver={Microsoft Text Driver (*.txt; *.csv)}" _
   , "DBQ=" & goFS.GetAbsolutePathName("..\data") _
), ";")
Dim sSQL : sSQL   = "SELECT O.* FROM [old.txt] O LEFT JOIN [new.txt] N ON O.MD5 = N.MD5 WHERE N.MD5 IS NULL"
oDb.Open sCS
Dim oRS : Set oRS = oDb.Execute(sSQL)
If Not oRS.EOF Then WScript.Echo oRS.GetString(2, , "|", vbCrLf, "NULL")
oDB.Close

输出:

6d5f1279d4deccbaeef5d074b13ed2f4|.\old\b\100_1608.jpg
26ff43419c4f30764fb015f6d7c869c1|.\old\b\100_1609.jpg

新增:

通过使用

Dim sSQL : sSQL   = "SELECT O.*, N.PATH FROM [old.txt] O INNER JOIN [new.txt] N ON O.MD5 = N.MD5"

你可以获取重复项:

d95e29e2c0172dea438b12c418b09fd3|.\old\a\100_1610.jpg|.\new\c\100_1610.jpg
d95e29e2c0172dea438b12c418b09fd3|.\old\b\100_1610.jpg|.\new\c\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224|.\old\a\100_1601.jpg|.\new\c\100_1601.jpg
19f9cda002c951f7a9f870ce74fb1224|.\old\b\100_1601.jpg|.\new\c\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713|.\old\a\100_1600.jpg|.\new\a\100_1600.jpg
32b154f796303a8e9caff0c9d55ba713|.\old\b\100_1600.jpg|.\new\a\100_1600.jpg

(参见相同方法,类似问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接