使用Automator在finder中获取文本文件的内容

Use Automator to get content of text files in finder

我正在尝试创建一个 automator-app,我可以在其中放置一个 finder-folder。它需要过滤所有(数千个)txt文件并将内容传递给"Text to Audio File"

但唯一可用的操作是获取 TextEdit 文档的内容,这是当前打开的 TextEdit 文档。

有没有办法只获取所选文档的内容?我认为这是很常见的用法?

在 Automator 中,将“运行 AppleScript”操作添加到您的工作流程中,并将以下 AppleScript 代码插入该“运行 AppleScript”操作中。

基本上,代码将获取 Finder 中当前选定的文件,如果当前选定文件的扩展名是“txt”,它将将该文本文件的内容传递到您的下一个工作流程操作中,这将是…文本到音频文件

tell application "Finder"
    set theSelectedFile to (get selection)
end tell
tell application "System Events"
    set nameExtension to name extension of (theSelectedFile as alias)
    set fileName to name of (theSelectedFile as alias)
end tell
if nameExtension is "txt" then
    set theContent to read (theSelectedFile as alias)
    set the clipboard to fileName as text
else
    return
end if
return theContent

接下来您将创建一个新的 AppleScript 变量并将其插入到“文本到音频文件”操作的“另存为”字段中。使用值 theNameset theName to the clipboard,如图所示在上面的屏幕截图中。这样做会将您新创建的音频文件的名称设置为原始源文本文件的名称

考虑到您要处理的文件数量庞大,并且需要将其内容转换为语音音频,我觉得这个特定问题更适合 bash 脚本而不是 AppleScripting。

这是我提出的 Automator 工作流程的屏幕截图,我相信它可以满足您的所有需求:

两个脚本(shell script 和 AppleScript)复制在这个答案的底部,用于简单的复制粘贴,但每个脚本的内容都在屏幕截图中完全可见。

概览

此工作流旨在作为 Finder 中的 服务 运行,这将使您 select 一个文件夹,对吧- 单击,然后 运行 弹出上下文菜单中的工作流。您还可以为其分配键盘快捷键。

文件夹被传递到工作流中。检索其内容,为工作流提供文件夹内的文件列表。这些被发送到 shell 脚本中。

shell 脚本导航到提供的文件夹并创建一个名为 "Audio" 的子文件夹,其中将保存音频文件。然后它循环遍历提供的文件夹中的每个文件。如果该文件不是 .txt 文件,则将其传递。否则,命令行工具 say 用于将每个文件的内容转换为语音音轨。我 select 为它配了一个说普通话的声音 ("Sin-ji")。音频文件使用的数据格式为aac,避免了以后在iTunes中进行二次转换。文件格式使用文件扩展名 .m4b,这可能看起来很陌生,但本质上是一个封装在 mp4 包装器中的 aac 文件,文件扩展名根据 Apple 的建议进行了更改。 .m4b 扩展告诉 macOS 该音频文件是 iTunes 有声读物(Apple 使用的其他文件是 .m4a 用于常规音频,.m4r 用于铃声).使用 .m4b 文件扩展名的妙处在于,当它被导入 iTunes 时,它会立即被识别为有声读物,并被放置在有声读物部分。

shell 脚本 returns "Audio" 目录的路径,现在填充有声读物文件。工作流程检索此目录的内容,即有声读物文件,并将它们导入 iTunes,而不进行任何进一步的转换。他们直接被送到图书馆,最后进入有声读物部分。

烦人的一点是:似乎当 iTunes 将新文件导入其库时,它会暂时锁定这些文件,大概是在文件被复制时,扫描文件,并写入元数据。在此期间,无法设置新导入曲目的任何属性,并导致 "File permissions error".

持续时间因系统而异,可能还取决于导入的文件数量。

在工作流程中插入 5 秒的暂停,让文件有足够的时间在我的系统上解锁,然后再继续最终的 AppleScript。

根据您的要求,此 AppleScript 的唯一工作是使用文件名中下划线 ("_") 之前的部分来命名相册,这就是它的作用。如果此时文件轨道全部解锁,它会做得很漂亮。如果任何一个轨道仍然被锁定,它会导致脚本和工作流抛出错误。

(奇怪的是,放入一个错误处理程序来捕获错误并防止它停止脚本似乎也阻止了属性的设置。iTunes 中出现了一些错误AppleScript,但这并不让我感到惊讶。)


脚本

Shell (bash)

    cd "$(dirname "")"      # Go into supplied folder
    mkdir -p "Audio"        # Create a folder for the audio files
    cd "Audio"

    shopt -s nocasematch    # For case-insensitive regex matching

    for f in "$@"; do        # Loop thru files; txt → m4b (audiobook)
        fn=$(basename "$f")
        [[ "${f##*.}" =~ txt ]] && \
        say --voice=Sin-ji \
            --output-file="${fn%.*}.m4b" \
            --input-file="$f" \
            --file-format=m4bf \
            --data-format=aac
    done

    pwd                     # Return the present working directory
                            # i.e. the "Audio" folder

AppleScript

    use application "iTunes"
    property text item delimiters : "_"

    on run {input, parameters}

        repeat with m4b in the input
            set m4b's album to text item 1 of (m4b's name as text)
        end repeat

    end run

下载工作流程

最后,我已将 Automator 服务工作流程上传到 download,让您不必从头开始重新创建。它应该在接下来的 30 天内可用。