使用 Applescript/mkdir 创建具有变量名称的嵌套文件夹



>我正在尝试创建一个提示输入作业名称的 applescript,然后创建一个所需的目录,在其中创建具有作业名称的文件夹。然后,它应该在初始文件夹中创建一系列子文件夹,其名称包括"作业名称-链接"和"作业名称-PDF"等。

我从不同的来源拼凑了这个脚本,并希望得到有关如何改进它的反馈,因为我确信它像罪恶一样丑陋。

tell application "Finder"
activate
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Links")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-PDFs")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Supplied")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Versions")
end tell

任何想法和评论将不胜感激。这是我第一次尝试脚本。我想我会发布这个,因为我多年来一直在寻找这个特定的用例,只找到了零碎的东西。希望有人可以帮助我,这样其他人也会发现它很有用。

另一个想法是在某处创建所需文件夹结构的模板,然后让脚本复制带有客户端前缀的结构。 此方法的几个好处是,如果将文件夹添加到模板中,则无需更改脚本(处理程序也将添加到现有结构中),并且您不必弄清楚如何编写复杂(或大型)结构的脚本。

property template : "/path/to/template/folder" -- the folder structure to copy from

on run -- example
    set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
    set folderPath to (choose folder with prompt "Select a location for the client folder")
    tell application "Finder" to try
        set clientFolder to (make new folder at folderPath with properties {name:jobNum})
    on error number -48 -- folder already exists
        set clientFolder to (folderPath as text) & jobNum
    end try
    copyFolderStructure_toFolder_withPrefix_(template, clientFolder, jobNum)
end run

to copyFolderStructure_toFolder_withPrefix_(source, destination, additions) -- copy folder structure using mkdir
    set {source, destination} to {source as text, destination as text}
    if source begins with "/" then set source to POSIX file source
    if destination begins with "/" then set destination to POSIX file destination
    set {source, destination} to {source as alias, destination as alias}
    set additions to additions as text
    tell application "Finder" to set theFolders to (folders of entire contents of source) as alias list
    set folderNames to ""
    repeat with someFolder in theFolders -- set up the folder names parameter for the shell script
        set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
        set namePieces to text items of (text ((count (source as text)) + 1) thru -2 of (someFolder as text))
        set AppleScript's text item delimiters to ("/" & additions)
        set namePieces to space & quoted form of (additions & (namePieces as text))
        set AppleScript's text item delimiters to tempTID
        set folderNames to folderNames & namePieces
    end repeat
    do shell script "cd " & quoted form of POSIX path of destination & "; mkdir -p" & folderNames
end copyFolderStructure_toFolder_withPrefix_

你可以做这样的事情:

      set TID to AppleScript's text item delimiters
-- Ensure the answer is formatted properly
repeat
    try
        set theAnswer to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
        set AppleScript's text item delimiters to "-"
        set {jobNum, jobDes} to {text item 1 of theAnswer, text item 2 of theAnswer}
        exit repeat
    on error
        display dialog "Please enter your response in this format [JobNumber]-[Description]" buttons {"Cancel", "Try again"} default button "Try again"
    end try
end repeat
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
set folderNames to {"-Links", "-PDFs", "-Supplied", "-Versions"}
repeat with aName in folderNames
    do shell script "mkdir -p " & quoted form of (folderpath & jobNum & "-" & jobDes & "/" & jobNum & "-" & jobDes & aName as text)
end repeat
set AppleScript's text item delimiters to TID

mkdir 可以创建一个层次结构,只需将这些名称放在 {} 中即可例 : '/destFolderPath/jobName/prefix'{"suffix1","suffix2","suffix3","suffix4"}

这是脚本。

set jName to my getJobNum()
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "mkdir -p " & (quoted form of (folderpath & jName & "/" & jName)) & "{"-Links","-PDFs","-Supplied","-Versions"}"
on getJobNum()
    activate
    text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
    tell the result to if it is not "" then return it
    getJobNum() -- else text returned is empty
end getJobNum

重要提示,如果您打算在名称中使用斜杠,则必须将它们替换为冒号字符,很容易在脚本中添加处理程序来替换它们,否则它将创建其他子文件夹。

我不是脚本编写者,但我正在寻找相同类型的结构化文件夹解决方案。在回顾了这些其他示例之后,我想出了一个稍微修改的版本,用于为我们的设计师组设置项目文件夹。

set TID to AppleScript's text item delimiters
-- Ensure the answer is formatted properly
repeat
    try
        set theAnswer to text returned of (display dialog "Please create a job folder, with the name in this format:" default answer "JobNumber-JobCode-ClientDescription")
        set AppleScript's text item delimiters to "-"
        set {jobNum, JobCod, CliDes} to {text item 1 of theAnswer, text item 2 of theAnswer, text item 3 of theAnswer}
        exit repeat
    on error
        display dialog "Please enter your job details in this format [JobNumber]-[JobCode]-[ClientDescription]" buttons {"Cancel", "Try again"} default button "Try again"
    end try
end repeat
set folderpath to POSIX path of (choose folder with prompt "Where to create your project folder?")
set folderNames to {"Links", "Client_input", "SourceBuilds", "Review-Proofs"}
repeat with aName in folderNames
    do shell script "mkdir -p " & quoted form of (folderpath & jobNum & "-" & JobCod & "-" & CliDes & "/" & aName as text)
end repeat
set AppleScript's text item delimiters to TID

我正在使用 jackjr300 脚本的变体来生成网站文件夹模板/

do shell script "mkdir -p " & (quoted form of (folderpath & jName & "/")) & "{"codey","js","fonts","images"}"

加上另一个运行以生成子文件夹,并使用现有框架和脚本填充这些子文件夹,并使用重复文件夹操作。

非常方便谢谢...!

改进脚本的第一件事就是不要使用 shell 脚本。Shell 脚本就像手提钻,但您正在做的事情只需要最小的手持锤。

这是您的原始脚本:

tell application "Finder"
activate
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Links")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-PDFs")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Supplied")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Versions")
end tell

与更易于读取、写入和维护的"去壳"版本相比:

tell application "Finder"
    activate
    set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
    set theClientFolder to (choose folder with prompt "Select client folder")
    set theSubFolderNames to {"Links", "PDFs", "Supplied", "Versions"}
    repeat with theSubFolderName in theSubFolderNames
        make new folder at theClientFolder with properties {name:jobNum & "-" & theSubFolderName}
    end repeat
end tell

请注意,变量"folderpath"已更改为"theClientFolder",因为选择文件夹不返回路径,而是返回所选文件夹的别名对象。用于告诉 Finder 创建新文件夹的命令是"在 [要创建文件夹的别名]处创建新文件夹",因此您无需将该别名转换为路径即可在其中创建新文件夹。

另请注意,文件夹的名称已在列表中声明为变量,这使它们更易于阅读或以后更改。即使是不了解AppleScript的人也可以打开此脚本并将" PDF"文件夹的名称更改为"文档"或类似名称。

我可以建议的另一个改进是使你从用户那里收集输入的方式更加复杂。您似乎要求除客户端文件夹以外的 2 项信息——作业编号和作业描述——因此请使用 2 个对话框,因为这对用户来说更容易并且更不容易出错,因为您可以给出 2 个您希望他们输入的实际示例。您还可以通过几种方式改善这些对话框的外观。您可以添加一些错误处理 - 如果用户取消您正在显示的对话框,则会产生错误。您可以通过检查用户是否单击"确定"来优雅地处理它们。

下面是一个脚本版本,其中用户输入进行了一些清理:

tell application "Finder"
    activate
    display dialog "Enter a job number:" default answer "100" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 180
    if the button returned of the result is equal to "OK" then
        set theJobNumber to the text returned of the result
        display dialog "Enter a job description:" default answer "Photos" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 180
        if the button returned of the result is equal to "OK" then
            set theJobDescription to the text returned of the result
            try
                choose folder with prompt "Select client folder:" default location (the path to the desktop folder as alias) without multiple selections allowed, invisibles and showing package contents
                set theClientFolder to the result
            on error
                set theClientFolder to ""
            end try
            if theClientFolder is not equal to "" then
                set theSubFolderNames to {"Links", "PDFs", "Supplied", "Versions"}
                repeat with theSubFolderName in theSubFolderNames
                    make new folder at theClientFolder with properties {name:theJobNumber & "-" & theJobDescription & "-" & theSubFolderName}
                end repeat
            end if
        end if
    end if
end tell

这将为您提供顶部显示"Finder"并包含 Finder 图标的对话框,该图标将在 180 秒后放弃(以防止超时错误),如果用户在任何时候按"取消",它将优雅地死亡而不会产生任何错误。您可以调整输入对话框的默认答案,以便它们帮助用户输入正确的输入,例如,如果作业编号为 4 位数字,请在此处输入 4 位数字。选择文件夹提示将从显示桌面开始 — 如果有存储所有客户端文件夹的磁盘或文件夹,您可以将其更改为另一个位置:

choose folder with prompt "Select client folder:" default location (disk "Clients" as alias) …

需要明确的是,shell脚本很棒,但我建议你只使用"do shell脚本"来获得UNIX层的独特功能,如PHP函数,Perl正则表达式等。在Mac层中已经可用的任何东西都将更容易,更安全地使用,并且更容易在AppleScript中阅读,写入和维护。尤其是非常基本的事情,例如创建文件夹。

我有一个从模板位置复制文件夹的解决方案。 它还创建了一个快捷方式,允许通过电子邮件向设计经理发送主题作为工作编号/项目编号

global jobNum
global newJobFolder
set jobNum to text returned of (display dialog "Enter a job number:" default answer "")
set jobName to text returned of (display dialog "Enter a job name:" default answer "")
set jobMgr to text returned of (display dialog "Enter account manager email:" default answer "")
set folderpath to (choose folder with prompt "Select client folder")
set newJobFolder to my newFold(jobNum, jobName, folderpath, jobMgr)

on newFold(theNumber, theName, thefolder, jobMgr)
    set emailAddress to jobMgr
    set emailSubject to theNumber & " -" & theName
    set bodyText to ""
    set emailLinkFileName to theNumber & " -" & theName
    set subNameList to {"Designs", "Documents", "Received"}
    set itemCount to count of subNameList
    set linkBody to "mailto:" & emailAddress & "?subject=" & my 
replace_chars(emailSubject, " ", "%20") & "&body=" & my 
replace_chars(bodyText, " ", "%20")
    tell application "Finder"
        set newJobFolder to (make new folder at thefolder with properties ¬
            {name:theNumber & " " & theName})
        repeat with i from 1 to itemCount
            set aSubFolder to make new folder at newJobFolder with properties {name:jobNum & " " & item i of subNameList}
            set theMailto to make new internet location file to linkBody at aSubFolder with properties {name:emailLinkFileName, name extension:"mailloc"}
            set the name extension of theMailto to "mailloc"
        end repeat
        duplicate file "Users:ace:Dropbox:Company:0000-1_E.xlsx" of startup disk to folder (jobNum & " Documents") of newJobFolder
        set name of the result to jobNum & " E.xlsx"
        set theMailto to make new internet location file to linkBody at newJobFolder with properties {name:emailLinkFileName, name extension:"mailloc"}
        set the name extension of theMailto to "mailloc"
    end tell
end newFold
-- Generic find and replace functionality
on replace_chars(this_text, search_string, replacement_string)
    set AppleScript's text item delimiters to the search_string
    set the item_list to every text item of this_text
    set AppleScript's text item delimiters to the replacement_string
    set this_text to the item_list as string
    set AppleScript's text item delimiters to ""
    return this_text
end replace_chars

最新更新