【问题标题】:List files in one folder structure which aren't in another列出一个文件夹结构中不在另一个文件夹结构中的文件
【发布时间】:2013-07-28 20:12:18
【问题描述】:

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

在我的 PC 上,我的所有照片都在 D:\Photos 下面的各个文件夹中。

我想要一些代码列出 C:\OldPhone\ 下面的所有 .jpg 文件,这些文件不在 D:\Photos\ 下面的任何位置

这有意义吗?只是强调一下,文件夹结构并不相同,我不介意文件在哪里,只要它在那里。文件名比较适用于初学者,添加大小的选项将是一个奖励!

CMD、VBS 或 powershell 会很好,但任何 Visual Studio 可以处理的东西也可以。

【问题讨论】:

  • 你已经尝试过什么了吗?

标签: powershell batch-file vbscript cmd


【解决方案1】:

试试这个:

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。这不适用于包含 = 的文件名。

【讨论】:

  • Batch/CMD 没有有关联数组。
  • @AnsgarWiechers cmd 早在他们最近得到的 bash 之前就有了这个关联数组。
  • CMD 没有关联数组。您可以拥有的最接近的是 Rob van der Woude 描述的模拟 here
  • 请查看Wikipedia article。您在批处理/CMD 中拥有的不是一个单一的数据结构,而是一堆具有有趣名称的单个变量。没有添加或删除操作,没有查找,也没有迭代器。
  • @Aacini 它甚至不使用数组,更不用说关联数组了。
【解决方案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 解决方案对我来说更简单。
【解决方案3】:
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

【讨论】:

    【解决方案4】:

    这就是我根据 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
    

    【讨论】:

      【解决方案5】:

      使用 fciv(和 grep):

      fciv .\old -r | grep jpg > old.txt
      fciv .\new -r | grep jpg > new.txt
      

      得到

      旧.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
      

      新的.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
      

      (参见same approach, similar problem

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-02
        相关资源
        最近更新 更多