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

Save a list of all applications in the Applications folder to a text file

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

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

试试这个代码...

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 提出了更快更有效地获取应用程序名称的建议(已在我的代码的第二行实现)

首先我建议使用 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'"

下面的这段代码成功了。我不得不在 "tell finder" 块之外调用写入函数。将其移出并将文件更改为“.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

很抱歉,您进行了这样的尝试,试图让这个与一些贡献一起工作,对我来说,使这个过程看起来比实际复杂得多。如果你想要的只是打印到文件的应用程序列表,你可以用十行 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

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"

此解决方案使用 shell 脚本,该脚本通过 AppleScript 的 do shell script 命令执行。

Bash解法:

基本上,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' 选项和参数 returns 只有最后一个组件匹配 .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 文件夹的位置,或生成的文本文件的保存位置 - 您需要转义任何可能存在的 space 字符.例如你的路径;

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

,包括几个 space。当在 Applescript do shell script 命令中指定时,这些将需要使用两个反斜杠 (\) 进行转义。例如:

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

或者,当 运行 直接通过命令行(例如 Terminal[=] 宁等效的 bash 解决方案时,使用单个反斜杠 (\) 进行转义196=] 申请)。例如:

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

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

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

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

为此,您可以利用 bash nl command and change the redirections to utilize a 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,您实质上包括了通过 ctrl + click 在 [= 中的应用程序上找到的所有应用程序147=]Finder 并选择 "Show Package contents".

2 如果每次都想在已有的.txt文件中追加一个新列表该脚本是 运行,根据您自己的答案中提供的解决方案,然后使用 >> 重定向运算符而不是单个重定向运算符 (>)。例如:

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