使用 Automator 在 finder 中获取文本文件的内容
Posted
技术标签:
【中文标题】使用 Automator 在 finder 中获取文本文件的内容【英文标题】:Use Automator to get content of text files in finder 【发布时间】:2018-08-09 00:21:33 【问题描述】:我正在尝试创建一个自动化应用程序,我可以在其中放置一个查找器文件夹。它需要过滤所有(数千个)txt文件并将内容传递给“文本到音频文件”
但唯一可用的操作是获取 TextEdit 文档的内容,这是当前打开的 TextEdit 文档。
有没有办法只获取所选文档的内容?我认为这是很常见的用法?
【问题讨论】:
我可能会提交一个替代解决方案,但我想澄清一下您是否希望将 Automator 工作流程传递给包含大量文本文件的文件夹;或选定的文件或文件?或者,也许,两者之一? 另外,您希望文件采用哪种音频格式?最后,你能给出一个包含非美国字符的示例文本的 sn-p 吗? 另外,您希望文件采用哪种音频格式?你能给出一个包含非美国字符的示例文本的 sn-p 吗?最后,是一个文本文件,旨在生成一个音频文件(因此您最终会得到数千个音频文件);还是合并文本文件以创建单个音频文件? @CJK 最喜欢的工作流程是在finder中选择一个文件夹,然后“右键单击->services->Convert2Audio。应该扫描文件夹中的txt文件,然后一个一个地扫描转换为 AIF,然后作为有声读物作为 AAC 导入 iTunes。这就是我现在拥有的 [1]:imgur.com/a/lggGmNs.png 每个文件应该是 1 个音频文件(章节)。 好的,这实际上很容易在 Automator 服务中使用 bash (shell) 脚本。可以使用 Automator 操作或通过 AppleScript 导入 iTunes。让我一起回答,我希望能证明如何做到这一点。有喜欢的声音吗? 【参考方案1】:考虑到您要处理的文件数量之多,并且需要将其内容转换为语音音频,我觉得这个特殊问题比 AppleScripting 更适合 bash 脚本。
这是我提出的 Automator 工作流程的屏幕截图,我相信它可以满足您的所有需求:
这两个脚本(shell 脚本和 AppleScript)在此答案的底部复制以进行简单的复制粘贴,但每个脚本的内容在屏幕截图中完全可见。
概述
此工作流程旨在作为Finder 中的服务 运行,您可以选择文件夹、右键单击并从弹出窗口运行工作流程上下文菜单。您还可以为其分配键盘快捷键。
文件夹被传递到工作流中。检索其内容,从而为工作流提供文件夹内的文件列表。这些被发送到 shell 脚本中。
shell 脚本导航到提供的文件夹并创建一个名为"Audio"
的子文件夹,其中将保存音频文件。然后它遍历提供的文件夹中的每个文件。如果文件不是.txt
文件,则将其传递。否则,命令行工具 say
用于将每个文件的内容转换为语音音轨。我为它选择了一个说普通话的声音(“Sin-ji”)。用于音频文件的数据格式是aac
,这样可以避免以后在 iTunes 中进行第二次转换。文件格式使用文件扩展名.m4b
,这可能看起来不熟悉,但本质上是封装在mp4
包装器中的aac
文件,文件扩展名已根据Apple 的建议进行了更改。 .m4b
扩展名告诉 macOS 音频文件是 iTunes 有声读物(Apple 使用的其他文件是 .m4a
用于常规音频,.m4r
用于铃声)。使用 .m4b
文件扩展名的一个很酷的事情是,当它被导入 iTunes 时,它会立即被识别为有声读物,并放置在有声读物部分。
shell 脚本返回"Audio"
目录的路径,现在填充有有声读物文件。工作流程检索此目录的内容,即有声读物文件,并将它们导入 iTunes 而不进行任何进一步的转换。它们会被直接送到图书馆,最后进入有声读物部分。
这是令人讨厌的一点:似乎当 iTunes 将新文件导入其库时,它会暂时锁定文件,大概是因为文件被复制,文件被扫描,并且元数据被写入。在此期间,无法设置新导入曲目的任何属性,并导致“文件权限错误”。
持续时间因系统而异,并且可能还取决于导入的文件数量。
在工作流程中插入 5 秒的暂停,让文件有足够的时间在我的系统上解锁,然后继续执行最终的 AppleScript。
根据您的要求,此 AppleScript 的唯一工作是使用文件名中下划线 ("_"
) 之前的部分来命名专辑,这就是它的作用。如果此时文件轨道全部解锁,它会做得很好。如果任何一条轨道仍处于锁定状态,则会导致脚本和工作流程抛出错误。
(奇怪的是,放入一个错误处理程序来捕获错误并防止它停止脚本似乎也阻止了属性的设置。iTunes AppleScript 中发生了一些错误,但这并没有不要让我感到惊讶。)
脚本
外壳(bash)
cd "$(dirname "$1")" # 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 天内可用。
【讨论】:
哇!这简直太疯狂了。比我要求的要多得多!非常感谢你。虽然我无法在 automator 中打开 automator 工作流程(它会因错误而崩溃),但它确实可以按预期工作。我会重新创建它只是为了学习。打开Application Specific Information: Performing @selector(_openRecentDocument:) from sender NSMenuItem 0x6080002b0c20 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<SBObject 0x60c000e55b10> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
时出现此错误【参考方案2】:
在 Automator 中,将“运行 AppleScript”操作添加到您的工作流程中,并将以下 AppleScript 代码插入到该“运行 AppleScript”操作中。
基本上,代码将在 Finder 中获取当前选定的文件,如果当前选定的文件具有“txt”扩展名,它将将该文本文件的内容传递给您的下一个工作流操作,即... Text到音频文件
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 变量并将其插入“文本到音频文件”操作的“另存为”字段中。使用值 theName
和 set theName to the clipboard
,如上面的屏幕截图所示。这样做会将新创建的音频文件的名称设置为原始源文本文件的名称
【讨论】:
太好了!但似乎 theContent 不适用于非美国角色。如果我将它输出为一个新的文本文件而不是音频文件,我会得到这个... /跨度> 对theSelectedFile
的每个引用都将其强制转换为alias
。也许在声明中这样做更明智:set theSelectedFile to selection as alias
。当然,如果选择了多个文件,您的脚本会抛出错误,因为selection
将返回一个列表。 Finder 还可以获得name extension
和name
属性,因此当您已经在 Finder 块中时切换到 系统事件 是很奇怪的。
我可能会这样做:tell application "Finder" to tell item 1 of (selection as list) to set [selectedFile, filename, nameExtension] to [it, name, name extension]
。这样可以一次性检索所有属性,不会因为多选而报错。以上是关于使用 Automator 在 finder 中获取文本文件的内容的主要内容,如果未能解决你的问题,请参考以下文章
Mac Automator 在 iTunes 中“获取信息”,然后按下一步直到最后一首歌曲