为什么Swift不仅仅用于开发应用
\n\n当听到“Swift”时,第一反应通常是iOS开发、Xcode、故事板和无穷无尽的约束。但这个语言还有另一面,并非所有人都了解。Swift是macOS上任务自动化的强大工具。这里指的不是编译应用程序,而是日常的普通事务:重命名上百个文件、解析CSV报告、在18:00发送通知或收集服务器日志。
\n\n为什么选择Swift而不是Python或Bash?因为Swift:
\n- \n
- 原生支持macOS(可访问
Foundation、Dispatch、UserNotifications); \n - 无需虚拟环境和依赖(如果不涉及SPM); \n
- 提供清晰的编译错误——不会像Bash那样花一小时寻找多余的空格; \n
- 可以一行命令作为脚本运行:
swift myScript.swift。 \n
在本文中,我将向您展示几个Swift自动化的真实场景。您可以复制代码,在本地运行,更重要的是,理解如何编写自己的实用工具。开始吧!
\n\nSwift脚本的结构:最少理论
\n\n要编写Swift自动化脚本,您不需要Xcode。只需终端和任意文本编辑器。创建一个文件script.swift,然后运行命令:
swift script.swift\n\nSwift会自动编译并执行代码。如果脚本较大且希望加速重复运行,可以预先编译:swiftc -O script.swift -o script,然后直接运行二进制文件。
我们接下来要写的内容都开箱即用——无需任何第三方库。只需Foundation,它会自动加载。
场景一:批量重命名文件
\n\n想象一下:您有一个包含照片的文件夹IMG_001.jpg、IMG_002.jpg……IMG_100.jpg。您想将它们重命名为Vacation_1.jpg、Vacation_2.jpg,以此类推。手动操作需要100次。用脚本只需0.5秒。
import Foundation\n\nlet fileManager = FileManager.default\nlet currentPath = fileManager.currentDirectoryPath\n\nguard let files = try? fileManager.contentsOfDirectory(atPath: currentPath) else {\n print("无法读取文件夹")\n exit(1)\n}\n\nlet imageFiles = files.filter { $0.hasSuffix(".jpg") || $0.hasSuffix(".png") }\n\nfor (index, file) in imageFiles.enumerated() {\n let newName = "Vacation_\\(index + 1)." + (file.hasSuffix(".jpg") ? "jpg" : "png")\n let oldURL = URL(fileURLWithPath: currentPath).appendingPathComponent(file)\n let newURL = URL(fileURLWithPath: currentPath).appendingPathComponent(newName)\n \n do {\n try fileManager.moveItem(at: oldURL, to: newURL)\n print("✅ \\(file) → \\(newName)")\n } catch {\n print("❌ 文件\\(file)出错: \\(error.localizedDescription)")\n }\n}\n\n工作原理:
\n- \n
FileManager.default— 访问文件系统; \n contentsOfDirectory— 获取当前文件夹中的文件列表; \n - 仅筛选图像文件; \n
- 通过
moveItem重命名(是的,在Swift中重命名就是移动操作)。 \n
您可以轻松调整脚本:更改前缀、扩展名、在文件名中添加日期。这已经是一个实用的Swift脚本,每天都能节省时间。
\n\n额外技巧:添加日期后缀
\n\nlet dateFormatter = DateFormatter()\ndateFormatter.dateFormat = "yyyy-MM-dd"\nlet dateString = dateFormatter.string(from: Date())\n\nfor (index, file) in imageFiles.enumerated() {\n let newName = "\\(dateString)_\\(index + 1).jpg"\n // ... 后续代码与上方示例相同\n}\n\n