Applescript:如何设置';移动到';文件夹根据文件名将文件按字母顺序排序?

Applescript:如何设置';移动到';文件夹根据文件名将文件按字母顺序排序?,applescript,subdirectory,Applescript,Subdirectory,我正在尝试创建一个“文件夹操作”,该操作将根据文件名的第一个字母为字母表的每个字母组织新文件添加到子文件夹中 我编写了以下代码,可以将添加到子文件夹“A”中的所有内容作为起点,但现在我遇到了一个块 on adding folder items to thisfolder after receiving added_items repeat with i from 1 to number of items in added_items set this_item to (item i of

我正在尝试创建一个“文件夹操作”,该操作将根据文件名的第一个字母为字母表的每个字母组织新文件添加到子文件夹中

我编写了以下代码,可以将添加到子文件夹“A”中的所有内容作为起点,但现在我遇到了一个块

on adding folder items to thisfolder after receiving added_items
repeat with i from 1 to number of items in added_items
    set this_item to (item i of added_items)
    set DestinationFolderName to "A"
    tell application "Finder"
        move this_item to folder DestinationFolderName of thisfolder with replacing
    end tell
end repeat
end adding folder items to
我现在的难题是如何将
设置DestinationFolderName为“A”
以响应此项的文件名

我尝试了
将DestinationFolderName设置为filename的text 1到text 1
和其他一些迭代,但问题似乎是找到提取第一个字母的文件名


非常感谢您的帮助。

首先,我们不鼓励您将文件移动到文件夹操作文件夹的子文件夹中,因为在您创建子文件夹时,文件夹操作会再次触发,这可能会导致无限循环

要将文件移动到一个可以动态创建的文件夹中,shell命令
同上
是首选解决方案,因为它能够隐式创建中间目录

此代码使用桌面上的文件夹
Test
作为目标位置(后面的斜杠非常重要),并使用处理程序在
AppleScriptObjC
的帮助下获取文件名的大写首字母

同上
复制文件时,需要额外的
rm
行来删除源文件

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

use framework "Foundation"

on adding folder items to thisfolder after receiving added_items
    set destinationFolder to POSIX path of (path to desktop) & "Test/"
    repeat with i from 1 to number of items in added_items
        set this_item to item i of added_items
        tell application "System Events" to set fileName to name of this_item
        set prefix to uppercasedFirstCharacter(fileName)
        set destinationFile to destinationFolder & prefix & "/" & fileName
        do shell script "ditto " & quoted form of POSIX path of this_item & space & quoted form of destinationFile
        do shell script "rm " & quoted form of POSIX path of this_item
    end repeat
end adding folder items to


on uppercasedFirstCharacter(theString)
    set cocoaString to current application's NSString's stringWithString:theString
    return (cocoaString's substringToIndex:1)'s uppercaseString() as text
end uppercasedFirstCharacter

正如@vadian提供的答案所述,使用附加的文件夹操作命令将文件移动到文件夹的子文件夹中从来都不是一个好主意

出于这个脚本的目的,我在我的桌面上创建了一个名为“new Destination”的新(移动到)文件夹,其中将包含子文件夹“a”、“B”、“C”等

例如,如果要移动的文件以字母“D”开头,而在名为“New destination”的文件夹中没有相应的移动到名为“D”的目标文件夹,则将自动创建文件夹“D”

如果要移动的文件名的第一个字母是小写,则可能创建的相应文件夹将从小写改为大写

property DestinationFolderName : missing value
property moveToFolder : (path to desktop folder as text) & "New Destination"

on adding folder items to this_folder after receiving these_items
    repeat with i from 1 to number of items in these_items
        set this_item to item i of these_items
        tell application "Finder"
            set fileName to name of item this_item
            set DestinationFolderName to character 1 of fileName
        end tell

        -- SATIMAGE scripting addition is needed for next command
        set DestinationFolderName to uppercase DestinationFolderName

        tell application "Finder"
            set checkExists to moveToFolder & ":" & DestinationFolderName
            try
                if not (exists of checkExists) then
                    make new folder at moveToFolder ¬
                        with properties {name:DestinationFolderName}
                end if
            end try
            move this_item to folder DestinationFolderName of folder moveToFolder with replacing
        end tell
    end repeat
end adding folder items to

我可以看出您已经在这方面得到了帮助,但我想提供另一种替代解决方案,它不使用外部框架或第三方工具(当然,使用这些工具没有任何问题)

我还想就使用关注的文件夹作为根目录的问题发表意见,您可以在其中创建更多的子文件夹,我将在演示脚本后执行以下操作:

    property alphabet : "ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz"


    on adding folder items to thisfolder after receiving added_items
        
        tell application "Finder" to ¬
            repeat with this_item in the added_items
                get this_item's name
                get the first character of the result
                my capitalise(the result)

                set DestinationFolderName to the result
                
                if not (exists folder DestinationFolderName in folder thisfolder) then ¬
                    make new folder in folder thisfolder with properties ¬
                        {name:DestinationFolderName}
                
                move this_item to folder DestinationFolderName of folder thisfolder
            end repeat
        
    end adding folder items to


    to capitalise(l as text)
        local l
        
        considering case
            set x to (the offset of l in the alphabet) mod 27
        end considering
        
        return character x of the alphabet
    end capitalise
您会注意到,这个脚本包含一个子例程(处理程序),我编写了一个名为
capitalize()
。它接受字母表中的一个字母,并基本上只用一行代码以大写形式返回它

将检索添加项的名称,并将其第一个字母大写。如果使用该字母命名的子文件夹不存在,则会创建一个子文件夹,然后将添加的项目移动到其中

它与脚本基本相同,只是增加了使用文件名的第一个字母动态创建文件夹的功能


关于无限回归。。。 关于在关注的文件夹中创建子文件夹所导致的无限循环的恐惧,强调这个问题是绝对正确的,因为它可能以他描述的方式表现出来。编写脚本时,如果要更改正在监视的文件夹,则需要注意这一点。通常,最简单的方法是避免这样做

但是,在某些情况下,您可能希望或需要将文件存储在正在监视的文件夹中。如果你从未被允许这样做,那么被监视的文件夹就不会真正起到文件夹的作用;它只是作为一个水滴(一个脚本,您可以将文件和文件夹拖放到其中以执行一些操作)

因此,虽然您一定要小心以这种方式使用监视文件夹,但您可以通过适当的保护措施来合理地使用它,以防止无限回归。举个简单的例子,假设您的脚本只需要对文件和进行排序,而不需要对文件夹进行排序;简单的解决方案是让脚本忽略它收到的任何文件夹

但是,事实上,我们甚至不需要在这里这样做:我们可以让它平等地处理文件和文件夹,不会发生任何不愉快的事情

以下是脚本中创建子文件夹然后将项目移动到其中的部分:

    if not (exists folder DestinationFolderName in folder thisfolder) then ¬
        make new folder in folder thisfolder with properties ¬
                    {name:DestinationFolderName}

    move this_item to folder DestinationFolderName of folder thisfolder
请注意,子文件夹始终在同一位置创建:
thisfolder
,它是正在监视的文件夹;它不尝试创建嵌套文件夹。另外,如果已经存在一个名为使用正在处理的信件的文件夹,那么它不会尝试创建另一个文件夹。最后一个潜在的担忧可能来自尝试将子文件夹移动到自身中。嗯,这不能在Finder中完成。这是不可能的。因此,脚本将无声地抛出错误并终止,这正是我们想要的

总结 我不会强迫你选择一种方法而不是另一种方法,也不会忽视一个熟练程序员的建议,比如


但是,如果您注意如何编写这些内容的脚本,您可以使用关注的文件夹将已排序的文件安全地存储在其子文件夹中。

太好了,没有想到循环效果!我已经尝试过你的代码,对这些文件非常有用,但唯一的问题是它会无限地重复新的字母表文件夹作为子文件夹-有什么想法可以修改吗?感谢您的回复!文件夹应该如何工作?脚本会为每个(第一个)字母创建一个子文件夹,并相应地分发文件和文件夹。如果文件夹为i,则必须进行的唯一更改