Macos 用于在文件夹中不存在具有相同名称和不同扩展名的其他文件时删除文件的Mac脚本

Macos 用于在文件夹中不存在具有相同名称和不同扩展名的其他文件时删除文件的Mac脚本,macos,shell,applescript,Macos,Shell,Applescript,我的文件夹里几乎没有文件。例如 1.jpg, 1.nef, 2.nef, 3.jpg, 3.nef 如果不存在同名的.jpg文件(在上面的列表中为2.nef),我想使用脚本删除.nef文件。 我的文件夹里有数千个文件。我无法在shell脚本中开发此逻辑。可以使用AppleScript完成此操作 谢谢, Arun[编辑以包含使用do shell脚本的更快版本] 更快的版本: set macStyleFF to choose folder set ff to (POSIX path of macS

我的文件夹里几乎没有文件。例如

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

谢谢,
Arun

[编辑以包含使用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
使用查找器“谁的子句”的速度不如使用查找器的速度:

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文件。[/p>[使用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
使用查找器“谁的子句”的速度不如使用查找器的速度:

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文件

这将使crgreen脚本更快一些

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

这将使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

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

我在第一部分中使用DoShell的更快版本:31s

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

[清理代码以提高效率(根据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

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

我在第一部分中使用DoShell的更快版本:31s

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

[清理代码以提高效率(根据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

在我看来,在一个大文件夹上使用which-claus是很慢的,在一个重复循环中多次搜索一个大文件夹寻找jpg文件也是很慢的。所以我建议你两个都不要

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

此脚本在一个包含1500个文件的文件夹上运行了2秒钟。文件夹中有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

在我看来,在一个大文件夹上使用which-claus是很慢的,在一个重复循环中多次搜索一个大文件夹寻找jpg文件也是很慢的。所以我建议你两个都不要

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

此脚本在一个包含1500个文件的文件夹上运行了2秒钟。文件夹中有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

您也可以在终端中运行如下命令:

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

删除
echo
以实际删除文件。

您也可以在终端中运行如下命令:

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


删除
echo
以实际删除文件。

我刚刚用我原来的which子句,Finder version在45秒时做了另一个测试。仔细想想。我的原始答案,使用Finder的子句:(45s)。adayzone的SE版本:1分钟(对不起,这是我得到的)。带初始do外壳:31s。w/do shell收集.nef的初始列表,do shell to do delete(rm):7-19s。regulus6633的SE版本:12s。劳里的猛击一轮:2秒。Re:AppleScript,我承认,如果不需要,我对使用系统事件有偏见,但如果它在某些方面更快,很高兴知道。注意:这些测试并不完美——在我最初的文件夹创建过程中,有多少孤儿被创建是随机的。大多数测试最终都是用重复文件夹tho完成的。很好的比较,感谢更新。我想知道为什么我的剧本有这么大的不同。你测量12秒,我测量2秒。我有一个SSD。你…吗?这就解释了差异。是的,就是这样!Hi CR。您应该避免在tell Finder块中包含“do shell脚本”。另外,正确的形式不是cd'&ff&',而是cd“"edformofff*”。我刚刚用我的原始which子句做了另一个测试,查找器版本为45s。仔细想想。我的原始答案,使用Finder的子句:(45s)。adayzone的SE版本:1分钟(对不起,这是我得到的)。带初始do外壳:31s。w/do shell收集.nef的初始列表,do shell to do delete(rm):7-19s。regulus6633的SE版本:12s。劳里的猛击一轮:2秒。Re:AppleScript,我承认,如果不需要,我对使用系统事件有偏见,但如果它在某些方面更快,很高兴知道。注意:这些测试并不完美——在我最初的文件夹创建过程中,有多少孤儿被创建是随机的。大多数测试最终都是用重复文件夹tho完成的。很好的比较,感谢更新。我想知道为什么我的剧本有这么大的不同。你测量12秒,我测量2秒。我有一个SSD。你…吗?这就解释了差异。是的,就是这样!Hi CR。您应该避免在tell Finder块中包含“do shell脚本”。另外,正确的格式不是cd'&ff&',而是cd“"ed form of ff*”。对不起,这确实有效,而且速度非常快。我无法计算时间,但它大约和我的applescript一样快(可能更快)。如果我只想在jpg存在的情况下删除nef文件,我将如何修改this@mcgrailm将
| |
替换为
&&
。抱歉,这确实有效,而且速度非常快。我无法计算时间,但它大约和我的applescript一样快(可能更快)。如果我只想在jpg存在的情况下删除nef文件,我将如何修改this@mcgrailm用
&&
替换
| |
。毫不奇怪,一号端子衬垫是最好的。我