将“应用程序”文件夹中所有应用程序的列表保存到文本文件

时间:2018-09-18 06:00:23

标签: applescript

我正在尝试编写一个基本程序,以将我所有应用程序的名称放置在MacOSX上指定文本文件中的应用程序文件夹中。这就是我写的。但是,每次运行时,它根本不会写入文件。该文件保持为空。对我做错了什么有帮助吗?

tell application "Finder"
    set writetoFile to POSIX file "/Volumes/3TB STORAGE/Downloads/00. All Installed Apps on Mac.rtf" as alias
    set appfolder to POSIX file "/Volumes/SierraM550/Applications/" as alias
    set info to every item of appfolder
    set names to []
    set n to 1
    repeat with apps in info
        set appname to name of apps
        set names to names & appname
        writeTextToFile(appname, writetoFile, false) of me
    end repeat
    return names
end tell

on writeTextToFile(theText, theFile, overwriteExistingContent)
    try

        -- Convert the file to a string
        set theFile to theFile as string

        -- Open the file for writing
        set theOpenedFile to open for access file theFile with write permission

        -- Clear the file if content should be overwritten
        if overwriteExistingContent is true then set eof of theOpenedFile to 0

        -- Write the new content to the file
        write theText to theOpenedFile starting at eof

        -- Close the file
        close access theOpenedFile

        -- Return a boolean indicating that writing was successful
        return true

        -- Handle a write error
    on error

        -- Close the file
        try
            close access file theFile
        end try

        -- Return a boolean indicating that writing failed
        return false
    end try
end writeTextToFile

5 个答案:

答案 0 :(得分:2)

尝试一下此代码...

tell application "Finder" to set appNames to name of application files in entire contents of (path to applications folder)

set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {", "}
set appNames to appNames as string
set AppleScript's text item delimiters to saveTID

writeToAFile(true, appNames)

on writeToAFile(trueOrFalse, theAppNames)
    set overwriteFile to trueOrFalse
    set theFile to (path to desktop as text) & "All Installed Apps on Mac.txt" --value can be changed
    set theFile to POSIX path of theFile
    set theText to paragraphs of theAppNames as string
    try
        set writeToFile to open for access theFile with write permission
        if overwriteFile is true then
            set eof writeToFile to 0
        end if
        write theText to writeToFile starting at eof
        close access theFile
    on error errMsg number errNum
        close access theFile
        set writeToFile to open for access theFile with write permission
        if overwriteFile is true then
            set eof writeToFile to 0
        end if
        write theText to writeToFile starting at eof
        close access theFile
    end try
end writeToAFile

特别感谢用户@CJK对于他提出的一种更快,更有效的方法来获取应用程序名称的建议(在我的代码的第二行中已实现)

答案 1 :(得分:2)

首先,我建议使用System Events,因为在使用Finder进行过滤时,whose的运行速度非常慢。

这是一个简单的解决方案,它收集所有应用程序名称并通过text item delimiters将列表连接起来。

由于write命令还支持POSIX路径,因此无需强制转换为HFS或别名的路径

set applicationFolder to path to applications folder
set destinationFile to "/Volumes/3TB STORAGE/Downloads/00. All Installed Apps on Mac.txt"

tell application "System Events"
    set applicationNames to name of files of applicationFolder whose name extension is "app"
end tell
set {TID, text item delimiters} to {text item delimiters, linefeed}
set namesText to applicationNames as text
set text item delimiters to TID

try
    set fileDescriptor to open for access destinationFile with write permission
    write namesText to fileDescriptor
    close access fileDescriptor
on error e number n
    try
        close access file destinationFile
    end try
    display dialog "Error: " & e & " - number: " & n buttons {"Cancel"} default button "Cancel"
end try

或者使用shell,它也可以在子文件夹和分发包中进行深度搜索,但可能要花一些时间(> 30秒),并且列出完整路径。

替换

tell application "System Events"
    set applicationNames to name of files of applicationFolder whose name extension is "app"
end tell
set {TID, text item delimiters} to {text item delimiters, linefeed}
set namesText to applicationNames as text
set text item delimiters to TID

使用

set namesText to do shell script "find /Applications -name '*.app'"

答案 2 :(得分:1)

很抱歉,您已经进行了这样的试用,试图使它与某些贡献一起起作用,对我来说,使该过程看起来比实际复杂得多。如您所说,如果您只是想要打印到文件的应用程序列表,则可以用AppleScript的十行代码来完成它:

    property filename : "00. All Installed Apps on Hack.txt"
    property directory : POSIX file "/Volumes/3TB STORAGE/Downloads/" as alias
    property appsfolder : POSIX file "/Applications/" as alias
    property text item delimiters : linefeed

    tell application "Finder"
        try
            make new file at directory with properties {name:filename}
        end try
        write (the displayed name of every application file ¬
            in the entire contents of the appsfolder as text) to ¬
            (the file named filename in the directory as alias)
    end tell

答案 3 :(得分:1)

AppleScript解决方案:

下面是一个高性能而简洁的AppleScript解决方案:

do shell script "{ find /Volumes/SierraM550/Applications/ -name '*.app' -prune | sed 's#.*/##; s/.[^.]*$//'; } | sort -f >/Volumes/3TB\\ STORAGE/Downloads/00.\\ All\\ Installed\\ Apps\\ on\\ Hack.txt"

此解决方案利用了一个外壳脚本,该外壳脚本是通过AppleScript的do shell script命令执行的。

重击解决方案:

基本上,AppleScript(以上)执行以下Shell脚本:

{ find /Volumes/SierraM550/Applications/ -name '*.app' -prune | sed 's#.*/##; s/.[^.]*$//'; } | sort -f >/Volumes/3TB\ STORAGE/Downloads/00.\ All\ Installed\ Apps\ on\ Hack.txt

此Bash命令可以在您的 Terminal 应用程序(或其他首选的命令行工具)中运行,并且输出结果将与前面提到的AppleScript相同。


说明:

以下内容提供了有关Shell脚本各组成部分的进一步说明:

  1. 阅读的第一部分;

    find /Volumes/SierraM550/Applications/ -name '*.app' -prune

    ,利用find命令。

    • 第一个参数; /Volumes/SierraM550/Applications/ Application 目录的路径。它通知find从哪里开始递归从目录树开始。

    • -name '*.app'选项和参数仅返回其最后一部分与.app匹配的路径名(即仅 application 文件)。

    • -prune选项可防止find进一步下降到当前文件 1 中。

  2. 下一部分:

    | sed 's#.*/##; s/.[^.]*$//'

    ,将find命令返回的每个匹配路径名通过管道传输到sed。这样只会从路径名中提取应用程序名称,即 basename 减去文件扩展名部分。

    • 第一个表达式s#.*/##删除最后一个正斜杠之前的部分。例如:

      echo "/Volumes/SierraM550/Applications/Safari.app" | sed 's#.*/##'
      # prints: `Safari.app`
      
    • 第二个表达式s/.[^.]*$//使用sed的s command仅提取应用程序名称。例如:

      echo "Safari.app" | sed 's/.[^.]*$//'
      # prints: `Safari`
      
  3. 上述1和2中的命令用花括号括起来;即{ ... ;}。这样可以对命令进行分组,并确保findsed命令都在当前shell上下文中执行,从而避免创建任何子shell。

  4. 下一部分;

    | sort -f

    ,将所有应用程序名称的列表通过管道传递到sort命令,以按字母顺序进行排序。

    • -f选项有助于确定排序顺序,确保将小写字符与大写字符等同对待。
  5. 最后一部分:

    >/Volumes/3TB\ STORAGE/Downloads/00.\ All\ Installed\ Apps\ on\ Hack.txt

    基本上将列表保存到.txt文件中。

    • > redirects排序后的应用程序名称列表(从 stdout )到一个新文件,将其保存在给定的路径位置。 2

有关指定路径的注意事项:

为任何一个提供路径时; Applications 文件夹的位置,或保存结果文本文件的位置-您需要转义可能存在的所有空格字符。例如您的路径;

  

/Volumes/3TB STORAGE/Downloads/00. All Installed Apps on Mac.rtf

,包含几个空格。在Applescript \\命令中指定时,必须使用两个反斜杠(do shell script)进行转义。例如:

/Volumes/3TB\\ STORAGE/Downloads/00.\\ All\\ Installed\\ Apps\\ on\\ Mac.rtf

或者,直接通过命令行(例如 Terminal 应用程序)运行等效的bash解决方案时,使用单反斜杠(\)转义。例如:

/Volumes/3TB\ STORAGE/Downloads/00.\ All\ Installed\ Apps\ on\ Mac.rtf

为列表中的每个应用程序编号:

我注意到在your own answer中,您为每个列出的应用程序添加了前缀;一个数字,后跟一个右括号和一个点。例如:

1). foo
2). baz
3). quux
...

要实现此目的,您可以使用bash nl命令并更改重定向以使用here string<<<)。下面是执行此操作的修订脚本:

修订的AppleScript:

do shell script "nl -w3 -s'). ' >/Volumes/3TB\\ STORAGE/Downloads/00.\\ All\\ Installed\\ Apps\\ on\\ Hack.txt <<<\"$({ find /Volumes/SierraM550/Applications/ -name '*.app' -prune | sed 's#.*/##; s/.[^.]*$//'; } | sort -f )\""

修订的Bash解决方案

本质上,经过修订的AppleScript(以上)执行以下Shell脚本:

nl -w3 -s'). ' >/Volumes/3TB\ STORAGE/Downloads/00.\ All\ Installed\ Apps\ on\ Hack.txt <<<"$({ find /Volumes/SierraM550/Applications/ -name '*.app' -prune | sed 's#.*/##; s/.[^.]*$//'; } | sort -f )"

您可能需要更改-w3部分以使数字正确对齐。如果您的应用程序少于一百个,请将其更改为-w2。如果您有超过一千个应用程序,则将其更改为-w4


脚注:

1 如果省略-prune选项,则最终的应用程序列表将更大。这是因为也可以找到应用程序包中的任何子应用程序。通过省略-prune,您实际上可以包含在 Finder 中的应用程序上通过 ctrl + click 单击找到的所有应用程序并选择“显示包内容”

2 如果要在每次运行脚本时将新列表追加到现有.txt文件中,请按照提供的解决方案进行操作在您自己的答案中,然后使用>>重定向运算符而不是单个(>)。例如:

>>/Volumes/3TB\ STORAGE/Downloads/00.\ All\ Installed\ Apps\ on\ Hack.txt


答案 4 :(得分:0)

下面的代码可以达到目的。我必须在“ tell finder”块之外调用write函数。将其移出并将文件更改为“ .txt”即可。感谢您输入换行符。我想要一个列表,每行一个应用程序。可行。

tell application "Finder"
    set writetoFile to POSIX file "/Volumes/3TB STORAGE/Downloads/00. All Installed Apps on Hack.txt" as alias
    set appfolder to POSIX file "/Volumes/SierraM550/Applications/" as alias
    set info to every item of appfolder

    set names to []
    set n to 1

end tell

writeTextToFile("", writetoFile, true) of me

repeat with apps in info
    set appname to name of apps
    set names to names & appname
    set appname to (n as string) & "). " & appname
    -- return appname
    writeTextToFile(appname, writetoFile, false) of me
    set n to n + 1
end repeat


on writeTextToFile(theText, theFile, overwriteExistingContent)
    try

        -- Convert the file to a string
        set theFile to theFile as string

        -- Open the file for writing
        set theOpenedFile to open for access file theFile with write permission

        -- Clear the file if content should be overwritten
        if overwriteExistingContent is true then set eof of theOpenedFile to 0

        -- Write the new content to the file
        -- write theText to theOpenedFile starting at eof
        write theText & return to theOpenedFile starting at eof
        -- Close the file
        close access theOpenedFile

        -- Return a boolean indicating that writing was successful
        return true

        -- Handle a write error
    on error

        -- Close the file
        try
            close access file theFile
        end try

        -- Return a boolean indicating that writing failed
        return false
    end try
end writeTextToFile