Applescript - 根据名称将文件组织到文件夹中

Applescript - Organize files into folders according to their names

我找到了这个 post:Applescript - 根据文件名的第一个单词创建文件夹 经过一些研究寻找类似的东西,但涉及更多步骤。 首先,我是 applescript 的新手。我能够看到一段代码并理解它的部分功能,但不是全部。

我有一堆这样命名的 pdf 文件: 类别 1 类别 2 类别 3 RestofTheName.pdf 正如您所想象的那样,每个类别的名称可能因一组 pdf 而异。

我想将它们组织在文件夹中,就像上面的脚本一样。 然后我想删除每个 pdf 的第一个单词(因为 CategoryX 部分仅用于组织目的而提供给文件名)。我已经用下面的代码完成了:

###################################################
#################### CATEGORY1 #######################
###################################################

###########################################################
# Organize files of a chosen folder using the first word of each file as name of the sub folders #
###########################################################

set chosenFolder to (choose folder)
tell application "Finder" to set fileList to files of chosenFolder

set TID to text item delimiters

set text item delimiters to space
repeat with aFile in fileList
    set fileName to name of aFile
    set textItems to text items of fileName
    if (count textItems) = 1 then
        set fileExtension to name extension of aFile
        set folderName to text 1 thru ((get offset of "." & fileExtension in fileName) - 1) of fileName
    else
        set folderName to first item of textItems
    end if
    set sourceFile to quoted form of POSIX path of (aFile as text)
    set destinationFile to quoted form of (POSIX path of chosenFolder & folderName & "/" & fileName)
    do shell script "ditto " & sourceFile & space & destinationFile
    do shell script "rm " & sourceFile
end repeat

set text item delimiters to TID

#####################################
# Remove first word of if each file inside every sub folder  #
#####################################

set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "

set pFolder to chosenFolder

processThisFolder(pFolder)

on processThisFolder(sourceFolder)
    set the theList to list folder sourceFolder without invisibles
    set sourceFolder to sourceFolder as string

    repeat with i from 1 to number of items in theList
        set thisItem to item i of theList
        set thisItem to (sourceFolder & thisItem) as alias
        set thisItemInfo to info for thisItem
        set isFolder to folder of thisItemInfo

        if isFolder is true then
            processThisFolder(thisItem)

        else
            set thisFileName to name of thisItemInfo
            #set withoutPrefix to text item -last text item) of thisFileName    -- solo deja la ultima palabra
            set withoutPrefix to text from text item 2 to -1 of thisFileName

            tell application "Finder"
                set name of thisItem to withoutPrefix
            end tell
        end if
    end repeat

end processThisFolder
set AppleScript's text item delimiters to oldDelims

到目前为止一切顺利。问题是现在我想继续整理 pdf 文件。我希望脚本遍历第一步创建的每个文件夹,再次检查每个文件名的第一个单词(最初是第二个)并将它们移动到文件夹中。他们用它来再次删除第一个单词。

然后再执行此步骤一次。所以我最终会得到这个结构:

+ Category1 Folder1
  - Category2 Folder1
    · Category 3 Folder1
       RestofTheName1.pdf
       RestofTheName2.pdf
       RestofTheName3.pdf
       RestofTheName4.pdf
       RestofTheName5.pdf

    · Category 3 Folder2
    · Category 3 Folder3

  - Category2 Folder2
    · Category 3 Folder1
    · Category 3 Folder2

+ Category1 Folder2
  - Category2 Folder1
  - Category2 Folder2
  - Category2 Folder3
  - Category2 Folder4

由于第一部分工作正常,我想这是重复以下步骤的问题:整理、重命名、整理、重命名。但是随着文件夹结构的每一步都在增长,我似乎无法让脚本正确地行动folder/subfolders/files.....

这是我现在所在的位置:

# CATEGORY1 

# Organize files of a chosen folder using the first word of each file as name of the sub folders 
###########################################################

set chosenFolder to (choose folder)
tell application "Finder" to set fileList to files of chosenFolder

set TID to text item delimiters

set text item delimiters to space
repeat with aFile in fileList
    set fileName to name of aFile
    set textItems to text items of fileName
    if (count textItems) = 1 then
        set fileExtension to name extension of aFile
        set folderName to text 1 thru ((get offset of "." & fileExtension in fileName) - 1) of fileName
    else
        set folderName to first item of textItems
    end if
    set sourceFile to quoted form of POSIX path of (aFile as text)
    set destinationFile to quoted form of (POSIX path of chosenFolder & folderName & "/" & fileName)
    do shell script "ditto " & sourceFile & space & destinationFile
    do shell script "rm " & sourceFile
end repeat

set text item delimiters to TID


# Remove first word of if each file inside every sub folder  #
###########################################################

set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "

set pFolder to chosenFolder

processThisFolder(pFolder)

on processThisFolder(sourceFolder)
    set the theList to list folder sourceFolder without invisibles
    set sourceFolder to sourceFolder as string

    repeat with i from 1 to number of items in theList
        set thisItem to item i of theList
        set thisItem to (sourceFolder & thisItem) as alias
        set thisItemInfo to info for thisItem
        set isFolder to folder of thisItemInfo

        if isFolder is true then
            processThisFolder(thisItem)

        else
            set thisFileName to name of thisItemInfo
            set withoutPrefix to text from text item 2 to -1 of thisFileName

            tell application "Finder"
                set name of thisItem to withoutPrefix
            end tell
        end if
    end repeat

end processThisFolder
set AppleScript's text item delimiters to oldDelims



# CATEGORY2

# Organize files inside every subfolder using the first word of each file name (which used to be the second word) as name of the sub sub folders 
###########################################################################################



tell application "Finder" to set subFoldersLevel1 to every folder of (entire contents of (chosenFolder))

set TID to text item delimiters

set text item delimiters to space
repeat with aFile in fileList
    set fileName to name of aFile
    set textItems to text items of fileName
    if (count textItems) = 1 then
        set fileExtension to name extension of aFile
        set folderName to text 1 thru ((get offset of "." & fileExtension in fileName) - 1) of fileName
    else
        set folderName to first item of textItems
    end if
    set sourceFile to quoted form of POSIX path of (aFile as text)
    set destinationFile to quoted form of (POSIX path of chosenFolder & folderName & "/" & fileName)
    do shell script "ditto " & sourceFile & space & destinationFile
    do shell script "rm " & sourceFile
end repeat

set text item delimiters to TID

欢迎任何帮助!!

您不必对文本定界符、递归处理程序或其他任何东西过于着迷。如果原始文件名的组成部分是由空格分隔的单词,则可以直接使用这些空格来确定类别。在下面的示例中,我获取文件名的 words(由空格和各种标点符号分隔的文本)并使用 shell 脚本从中创建目录结构:

on run -- example
    set chosenFolder to (choose folder)
    tell application "Finder" to set fileList to files of chosenFolder as alias list
    set skippedItems to ""
    repeat with anItem in fileList
        set theResult to process(anItem)
        if theResult is not "" then set skippedItems to skippedItems & theResult
    end repeat
    if skippedItems is not "" then display alert "Items were skipped:" message skippedItems
end run

# Create a directory structure from words of the file name and move/rename last item.
to process(theFile)
    set {folderPath, fileName, extension} to getNamePieces from theFile
    try -- guard
        set theWords to words 1 thru -2 of fileName
        set subdirectories to ""
        repeat with anItem in theWords -- build a directory tree from the words
            set subdirectories to subdirectories & anItem & "/"
        end repeat
        do shell script "cd " & quoted form of folderPath & "; mkdir -p " & subdirectories
        tell application "System Events" to set name of (move theFile to disk item (folderPath & "/" & subdirectories)) to (last word of fileName) & extension
    on error errmess -- skip it (no words - underscore separator, etc)
        log errmess
        return (fileName & extension & return)
    end try
    return ""
end process

#  Get posix path of the containing folder, the file name, and the extension.
to getNamePieces from someItem
    tell application "System Events" to tell disk item (someItem as text)
        set theContainer to POSIX path of container
        set {theName, theExtension} to {name, name extension}
    end tell
    if theExtension is not "" then
        set theName to text 1 thru -((count theExtension) + 2) of theName -- the name part
        set theExtension to "." & theExtension
    end if
    return {theContainer, theName, theExtension}
end getNamePieces