【问题标题】:Creating nested folders with variable names using Applescript/mkdir使用 Applescript/mkdir 创建具有变量名的嵌套文件夹
【发布时间】:2012-06-28 21:41:51
【问题描述】:

我正在尝试创建一个提示输入作业名称的applescript,然后是一个所需的目录,在该目录中创建一个带有作业名称的文件夹。然后它应该在初始文件夹中创建一系列子文件夹,其名称如“job name-Links”和“job name-PDFs”等。

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

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

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

【问题讨论】:

    标签: macos applescript finder mkdir


    【解决方案1】:

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

    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_
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

            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
      

      【讨论】:

        【解决方案3】:

        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
        

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

        【讨论】:

        • 我喜欢你从内部调用处理程序来创建循环的方式。
        • 您可以像这样调用处理程序 replace_chars() tell the result to if it is not "" then return my replace_chars(it,"/", ":") --- 对于那些不知道如何替换字符串中的字符的人, -->( macosxautomation.com/applescript/sbrt/sbrt-06.html)
        【解决方案4】:

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

        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
        

        【讨论】:

          【解决方案5】:

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

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

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

          非常方便,谢谢...!

          【讨论】:

            【解决方案6】:

            改进脚本的第一件事就是不要使用 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 的人也可以打开此脚本并将“PDFs”文件夹的名称更改为“Documents”或类似的名称。

            我可以建议的另一项改进是让您从用户那里收集输入的方式更加复杂。除了客户文件夹之外,您似乎还要求提供 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 脚本非常棒,但我建议您只使用“执行 shell 脚本”来获得 UNIX 层的独特功能,例如 PHP 函数、Perl 正则表达式等。 Mac 层中已经为您提供的任何内容都将更容易、更安全地使用,并且在 AppleScript 中更易于阅读、编写和维护。尤其是非常基本的事情,比如创建文件夹。

            【讨论】:

              【解决方案7】:

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

              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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-02-24
                • 2011-08-22
                • 2010-11-22
                • 1970-01-01
                • 2012-09-23
                • 1970-01-01
                • 1970-01-01
                • 2015-01-02
                相关资源
                最近更新 更多