【问题标题】:Mac script for deleting a file if another file with same name and different extension is not present in the folder如果文件夹中不存在另一个具有相同名称和不同扩展名的文件,则用于删除文件的 Mac 脚本
【发布时间】:2013-10-19 17:05:53
【问题描述】:

文件夹中的文件很少。例如。

1.jpg,
1.nef,
2.nef,
3.jpg,
3.nef

使用脚本,如果不存在同名的 .jpg 文件(在上面的列表中,2.nef),我想删除 .nef 文件。 我的文件夹中有数千个文件。我无法在 shell 脚本中开发这个逻辑。这可以使用 AppleScript 来完成吗?

谢谢, 阿伦

【问题讨论】:

    标签: macos shell applescript


    【解决方案1】:

    你也可以在终端中运行这样的命令:

    cd /path/to/directory; for f in *.nef; do [[ -e ${f%nef}jpg ]] || echo rm "$f"; done
    

    删除echo 以实际删除文件。

    【讨论】:

    • 抱歉,这确实有效,而且速度非常快。我无法计时,但它比我的 applescript 快(也许更快)。
    • 如果我只想在 jpg 存在的情况下删除 nef 文件,我将如何修改它
    • @mcgrailm 将|| 替换为&&
    【解决方案2】:

    这将使 CRGreens 脚本更快一点...

    set ff to choose folder
    
    tell application "System Events"
        set everyNef to files of ff whose name extension = "nef"
        repeat with thisNef in my everyNef
            set thisJpg to my getBaseName(thisNef) & ".jpg"
            if not (exists file thisJpg of ff) then delete thisNef
        end repeat
    end tell
    
    -- This handler is not limited to .jpg
    on getBaseName(aFile)
        tell application "System Events" to set {fileName, fileExt} to {name, name extension} of aFile
        return text 1 thru ((get offset of "." & fileExt in fileName) - 1) of fileName
    end getBaseName
    

    【讨论】:

    • 这有两个赞成是误导。我有部分责任,因为我首先投票支持 w|o 测试。在我的系统上,这是所有变体中最慢的。
    【解决方案3】:

    [使用 do shell 脚本编辑以包含更快的版本] 更快的版本:

    set macStyleFF to choose folder
    set ff to (POSIX path of macStyleFF)
    tell application "Finder"
        --first get all the .nef files (names)
        set everyNef to do shell script "cd '" & ff & "';ls *.nef" --name of every file of ff whose name ends with ".nef"
        set everyNef to (every paragraph of everyNef)
    
        repeat with thisNef in everyNef
            --use this list to see if there is a jpg of same name
            if file ((text 1 thru -5 of thisNef) & ".jpg") of macStyleFF exists then
                --it has a companion
            else
                --if not, send it to the trash
                delete (file thisNef of macStyleFF)
            end if
        end repeat
    end tell
    

    没有使用 Finder 'whose clause' 的快速版本:

    set ff to choose folder
    tell application "Finder"
        --first get all the .nef files (names)
        set everyNef to name of every file of ff whose name ends with ".nef"
        repeat with thisNef in everyNef
            --use this list to see if there is a jpg of same name
            if file ((text 1 thru -5 of thisNef) & ".jpg") of ff exists then
                --it has a companion
            else
                --if not, send it to the trash
                delete (file thisNef of ff)
            end if
        end repeat
    end tell
    

    请注意,这会在其中留下任何孤立的 jpg,但不会留下孤立的 .nef 文件

    【讨论】:

    • 不出意外,终端单线是最好的。我懒得把它放在一起!感谢劳里兰塔。
    【解决方案4】:

    在我看来,在大文件夹上使用 who 子句会很慢,并且在重复循环中多次搜索大文件夹以查找 jpg 文件的速度很慢。所以我建议你两者都不做。

    我们可以一次获取文件的名称,然后使用该名称列表进行搜索。另外,我们可以将该列表放入一个脚本对象中,这样当您处理大型列表时,脚本会变得更快。

    此脚本在 2 秒内在一个包含 1500 个文件的文件夹上运行。文件夹中有 1000 个 nef,其中 500 个没有 jpg 文件。

    set ff to choose folder
    set ffText to ff as text
    
    script s
        property everyFileName : missing value
    end script
    
    set inTime to current date
    tell application "System Events"
        set s's everyFileName to name of files of ff
    end tell
    
    repeat with aName in s's everyFileName
        if (text -3 thru -1 of aName) is "nef" then
            if (text 1 thru -4 of aName & "jpg") is not in s's everyFileName then
                tell application "System Events" to delete file (ffText & aName)
            end if
        end if
    end repeat
    set s's everyFileName to missing value
    
    set totalTime to (current date) - inTime
    return totalTime
    

    【讨论】:

    • 嗨轩辕。请注意,我在我的脚本中也使用了一个(顶级)脚本对象......“在我的 everyNef 中重复 thisNef”
    • 我喜欢这种方法... +1
    • 我确实注意到了 adayzdone。我从来没有那样用过它……我总是按照我在这里展示的方式来做……但是我看到了关于它的速度和使用的讨论。我只需要修改它,以便在开始使用它之前更好地理解它。
    【解决方案5】:

    我测试了 3 个版本,每个版本都有一个包含大约 1700 个文件的文件夹。 系统事件版本:61s。

    我在第一部分使用 do shell 的更快版本:31s。

    下面的方法使用另一个 do shell 删除文件:19(或更少——它在 9s 和 7s 中完成)。 [编辑:参见下面的注释和清理代码]

    set macStyleFF to choose folder
    set ff to (POSIX path of macStyleFF)
    set d to current date
    tell application "Finder"
        --first get all the .nef files (names)
        set everyNef to do shell script "cd '" & ff & "';ls *.nef" --name of every file of ff whose name ends with ".nef"
        set everyNef to (every paragraph of everyNef)
    
        repeat with thisNef in everyNef
            --use this list to see if there is a jpg of same name
            if file ((text 1 thru -5 of thisNef) & ".jpg") of macStyleFF exists then
                --it has a companion
            else
                --if not, send it to the trash
                --delete (file thisNef of macStyleFF)
                do shell script "rm '" & ff & thisNef & "'"
            end if
        end repeat
    end tell
    

    [清理代码以使其更高效(根据 adayzone 的建议)生成下面的脚本,该脚本的时间为 5-6 秒。]

    set macStyleFF to choose folder
    set ff to (POSIX path of macStyleFF)
    
    set everyNef to do shell script "cd '" & ff & "';ls *.nef" --name of every file of ff whose name ends with ".nef"
    set everyNef to (every paragraph of everyNef)
    
    repeat with thisNef in everyNef
        tell application "Finder" to file ((text 1 thru -5 of thisNef) & ".jpg") of macStyleFF exists
    --or ((do shell script "[ -f " & ff & ((text 1 thru -5 of thisNef) & ".jpg") & " ] && echo \"true\" || echo \"false\"") as boolean)
        --use this list to see if there is a jpg of same name
        if (result) then
            --it has a companion
        else
            --if not, send it to the trash
            --delete (file thisNef of macStyleFF)
            do shell script "rm '" & ff & thisNef & "'"
        end if
    end repeat
    

    【讨论】:

    • 我刚刚用我原来的 who 子句做了另一个测试,Finder 版本在 45s。去图吧。
    • 我的原始答案,使用 Finder 其子句:(45s)。 adayzone 的 SE 版本:1 分钟。 (对不起,这就是我得到的)。 w/initial do shell: 31s。 w/do shell 收集 .nef 的初始列表并执行 shell 删除 (rm):7-19 秒。 regulus6633 的 SE 版本:12s。 Lauri 的 bash 单线:2 秒。回复:AppleScript,我承认如果不需要,我对使用系统事件有偏见,但如果它在某些事情上更快,很高兴知道。注意:这些测试并不完美——在我的原始文件夹创建过程中创建了多少孤儿是随机的。大多数测试最终都是使用重复的文件夹完成的。
    • 很好的比较,感谢您的更新。我想知道为什么我的剧本有这么大的差异。你测量 12 秒,而我测量 2 秒。我有一个固态硬盘。你?这将解释差异。
    • 是的,这样就行了!
    • 嗨,CR。您应该避免在告诉 Finder 块中包含“执行 shell 脚本”。也不是 cd '" & ff & "' ,正确的形式是 cd " & ff * " 的引用形式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    相关资源
    最近更新 更多