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

时间:2012-06-27 12:44:53

标签: macos applescript finder mkdir

我正在尝试创建一个提示输入作业名称的AppleScript,然后创建一个所需的目录,在该目录中创建一个包含作业名称的文件夹。然后它应该在初始文件夹中创建一系列子文件夹,其名称如“job name-Links”& “工作名称 - 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

任何想法&评论将不胜感激。这是我第一次尝试编写脚本。我以为我会发布这个,因为我已经找到了这个特定用例多年,只发现了点点滴滴。希望有人可以帮助我,所以其他人也会觉得它很有用。

7 个答案:

答案 0 :(得分:0)

您可以这样做:

      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

答案 1 :(得分:0)

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

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 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

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

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

非常方便,谢谢......!

答案 5 :(得分:0)

您可以做的第一件事就是不要使用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”,因为choose文件夹不返回路径,它返回所选文件夹的别名对象。告诉Finder创建一个新文件夹的命令是“在[你想要创建文件夹的别名]创建新文件夹”,这样你就不需要将该别名转换成一个路径来在其中创建新文件夹。 / p>

另请注意,文件夹的名称已在列表中声明为变量,这使得以后更容易阅读或更改。即使是不懂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脚本很棒,但我建议你只使用“do shell script”来获得UNIX层的独特功能,比如PHP函数,Perl正则表达式等等。 Mac层中已经可以使用的任何内容都将更容易,更安全,并且更易于在AppleScript中进行读取,编写和维护。特别是基本的东西,如创建文件夹。

答案 6 :(得分:0)

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

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