mac上有自带的脚本工具,脚本编辑器。
AppleScript 是 Mac OS X内置的一种功能强大的脚本语言。
第一节 对象、属性和命令
AppleScript是一种面向对象(Object-Oriented,简称OO)的脚本语言,和现在主流的 面向对象程序语言一样,它拥有三个重要的OO术语:对象(Object)、属性(Property)和 命令(Command)。
命令:又称“方法”(Method)。顾名思义,命令就是指令,它告诉脚本/程序应该 去做什么。在非面向对象(面向过程)的语言中,命令或者方法可被成为“函数”。
第二节 标识符和关键字
首先值得说明的是:AppleScript的采用Unicode文字编码,并且不区分大小写。
标识符
标识符就是对象、属性、常量、变量等等的名称。
AppleScript规定:标识符必须以英语字母开头,可使用26个英语字母、10个阿拉伯数字以及下划线(_)。
特殊规则:如果标识符以“|”开头并结尾,则标识符可以使用任何Unicode字符,但是标识符名称本身是不包括“|”。避免使用符合“|”这一特殊规则的标识符。
关键词(设置红色)
关键字是在AppleScript语言写的保留字,这些词通常拥有特殊含义。关键字由小写字母组成:abcdefghijklmnopqrstuvwxyz,部分关键字由两个词组成。
第三节 数据类型
AppleScript中的变量名由一个词组成,中间不能留有空格。不能以数字开头,但数字可以在变量名中出现。命名允许使用下划线“_”。
-
Boolean (布尔型)
仅仅包含两个值:True和False
-
Number(数字)Integer(整型)和Real(实型)
分为整数和分数两大类,二者都可以是负数。 number类型变量之间可以进行四则运算和乘方运算等:
-
String(字符串)Text(文本型)
用双引号引起来表示这是字符串值("string")。
用转义字符“ ”在字符串中输出引号。
反斜杠在字符串中显示”。
获取字符串变量的长度(关键字the length of来获取)。
number和string之间的类型互换(使用“as 类型名”来显式声明)。
在目前的AppleScript中,Text和String两个类型是一致的。
String类和未提及的Unicode Text类是在AppleScript 2.0时代的东西,现在Text类已经完全代替了它们,但是 Apple®为了方便起见,保留了这两个类。根据《AppleScript Language Guide》2008年3月版,“ text, string, and Unicode text will all compare as equal”,三者完全一致。
-
Date(日期型)
如:date "2009年8月30日星期日 下午12:31:34"。
此格式的具体形式由“系统偏好设置-语言与文本”的相关设置决定。
-
Constant(常量型)
如:yes,no,ask
这些常量可以是已经被AppleScript预定义的,也可以是用户定义的不可变变量。这种 类型的数据一经确定不可更改。此外可以认为所有关键字都是常量型的数据
-
List(列表)
列表的表示格式为:
{"item1", "item2", "item3"}
使用&运算符可以直接将若干个列表中的元素合并并形成一个新的列表:
{"item1", "item2", "item3"}&{"item4", "item5", "item6"}
获取和更改列表中的元素:
(1)获取list中指定序号的元素有多种方法,例如:
set item 2 of modifiedList to "2"
set the second item of modifiedList to "second"
set the 2nd item of modifiedList to "2nd"
(2)可以为列表中的随机元素赋值,使用some item of关键字就可以了
(3)可以用the last item关键字来获取列表中的最后一个元素
(4)也可以用-1来获取最后一个元素,负数表示从列表尾端开始获取元素
注意获取item时不要越界,item 0也不可以
(5)获取整个列表,直接get就可以了(所有的变量类型同理)
获取子列表:
使用“items 开始序号 through 结束序号 of”可以获取list中的子列表
要逆向获取子列表,需要用到reverse关键字
set longList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set shortList to items 6 through 10 of longList
结果输出为:{6, 7, 8, 9, 10}
获取列表的元素个数:
使用length或count关键字均可
添加元素到列表末尾:
使用“set the end of 列表名 to 元素”实现
输出结果为:{1, 2, 3, 4, 5, {6, 7, 8, 9, 10}}
将string转换为list:
方法就是在set to语句后加一个as list声明
使用&可以连接string和list变量,结果的类型由&运算符之前的变量类型决定。
使用itemized关键字可以将一个string对象分割成单个的字符并组成一个新的列表,例如:
-- itemized string to character
set itemized to every character of stringAndString
输出结果为:{"H", "e", "l", "l", "o", " ", "A", "p", "p", "l", "e", "S", "c", "r", "i", "p", "t"}
分割和恢复字符串:可以将string分割为一个list。
首先通过AppleScript's text item delimiters来指定分割符号,然后通过every text item of来实现分割。方法如下:
<pre>
-- AppleScript's text item delimiters
set defaultDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set listAfterDelimiter to every text item of stringAndString
set AppleScript's text item delimiters to defaultDelimiters
get listAfterDelimiter</pre>
注意要首先保存AppleScript's text item delimiters,在分割字符串完成后记得要将其还原。
使用" "分割字符串结果为:{"Hello", "AppleScript"}
使用""分割字符串结果为:{"H", "e", "l", "l", "o", " ", "A", "p", "p", "l", "e", "S", "c", "r", "i", "p", "t"}
可以将分割后的list恢复为一个string。恢复过程是一个逆向的过程,方法如下:
<pre>
-- Restore list after delimiter to string
set defaultDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set restoredString to listAfterDelimiter as string
set AppleScript's text item delimiters to defaultDelimiters
get restoredString
</pre>
这里也要保存和还原AppleScript's text item delimiters。
-
Record(记录)
record类似于OC中的字典,其格式类似于:
{name1:value1, name2:value2, name3:value3}
其中name相当于字典中的key,value相当于字典中的value。
1.使用set to语句赋值
也可以利用name/value对来新建一个Record
2.使用name获取value
set tempValOfName to the name1 of aRecord
3.获取Record的name/value对数目
注意,record中的组成是属性(property)而不是元素(item),不要用item关键词来获取record中的属性。
获取record中的属性数目方法也是用count
4.Record与Dialog
在点击了Dialog中的某个按钮让Dialog消失后,Dialog将返回一个Record变量给程序,我们可以用button returned这个name去获取对应的value从而知道用户刚刚按下了哪个按钮,并将其反馈出来,
5.Record与Input text field
在对话框中我们可以通过适当的设计让它变成一个文本输入框,只需要一个default answer
确定数据类型-Class of 要确定一个数据到底是什么类型的,使用Class of语句
class of "string" 此代码得到结果text。
第四节 强制数据类型转换
有时默认的数据类型并不是我们想要的,比如"1"的数据类型为Text,而我们想要的是 Integer;另一个例子是命令要求的参数类型与实际类型不一致时,我们就需要强制类型转换 (Coercion)。
as关键字:用as关键字即可实现强制类型转换。用法:数据 as 类型 请注意,强制类型转换有时会丢失精度。
<pre>
1.99 as list --得到{1.99}
{a:1, b:2} as list --得到{1, 2},精度丢失(标识符丢失)!
--错误举例
"text2" as number --错误!Text中包含了无法转换成数字的字符。
1 as record --错误!无法获得标识符。
{1, 2} as record --错误!无法获得标识符。</pre>
第五节 运算符
- 数学运算符
特殊符号通过按住Option键加符号来输入。如÷用option和/组合键输入,≥用option和>输入。
在Java和C中,两个整型变量相除得到的还是整数,这就产生了3/2=1的情况。而在AppleScript中,即使是整
型变量相除,仍会得到小数。如:(3 as integer) / (2 as integer)结果仍然是1.5。
+,-,*,/,÷,^,div(整除),mod(取余)
- 比较运算符
所有运算符均返回Boolean(布尔型)数值,比较运算符表达方式非常多样。 - 逻辑运算符
and(逻辑与),or(逻辑或)和not(逻辑非)。 三个对参与运算的数据要求均为Boolean型,not为单目运算符。 - &运算符
简单来说这个是合并运算符。支持任何类型数据。以左边为主。
第六节 提取对象中的元素
- 提取字符串中的字母或单词
提取字符串中全部字母(单个Unicode字符),结果为List类型:
every character of 和 characters of 两个命令的功能完全一致。
提取字符串中全部单词:
every word of 和 words of 功能完全一致
提取指定未知的几个字符或单词,结果为List类型:
characters 3 through 5 of "A String"--结果:{"S", "t", "r"}
words 3 through 5 of "我的名字叫张三"--结果:{"名字", "叫", "张三"}
提取特定位 置的一个字符或单词,结果为Text:
word 2 of "This is a text"
character 3 of "This is a text"
ninth character of "This is a text"
特别注意:
第一个字符的位置是1,而不是0!
“through”可以缩写为“thru”
不推荐用序数词方法获得一个单词或字符
不推荐对于中文引用“word”相关语句 - 提取Finder文件列表
every file of desktop --获得桌面上所有文件(List类型),其内容很详细
files of desktop --同上
name of every file of desktop
现在提取符合指定条件的Finder文件列表
tell application "Finder" every file of desktop whose name begins with "a" --仅获得文件名以a开头的文件列表 every file of desktop where its name contains "a" --仅获得文件名包含a的文件列表 end tell
代码中的“begins with”“contains”可以用其他比较运算符代替。
新知识:whose和where its:两者功能基本一致,用于限定条件
第七节 添加注释和括号
AppleScript的注释形式,有两种:“ -- ”和“ (* ) ”,第一种类似于OC中的“ // ”,第二种类似于OC中的“ / */ ”。
从2.0版开始,AppleScript还支持使用#符号作为注释
给代码添加括号,控制运算优先级。
第八节 代码缩写
为了节省时间,将冗长的关键字缩写为几个字母也是非常有用的。此处举几例: application 简写为 app(编译时会补全)
end tell/repeat/try 简写为 end(编译时会补全)
through 简写为 thru
if语句 可省略 then(将在下一章节介绍)
第九节 读懂AppleScript字典
打开特定应用程序的AppleScript字典:
第1种方式.文件->打开字典->选择应用,查看各种属性和命令。
方式2.直接将应用程序(app文件)拖曳到Dock中的“脚本编辑器”图标上。
读懂AppleScript字典:
在左边的列中包含了指令和物件的 “套件”。当你选择了一个套件,你会在下面的显示窗中看到此套件所包含的所有东西。你可以通过点击第二列及第三列里的命令来缩小预览的范围。套件包含了 “指令” (圆形的C图标)和 “类” (方形的C图标),而 “类” 包含了 “属性”(P图标)和 “元素”(E图标)。要理解这些东西怎么工作在一起,最好的方法就是用字典来写一个脚本范例。
如何阅读字典(命令):
第一行说明词性和具体解释“创建一个新元素”
之后开始就是完整的命令语句所应该(或者可以)含有的内容:
- 体字是关键字,即必须一字不差的照打,如果带有[]则是 可以省略的(可选关键字)。
- 在黑体字后面、冒号前面的正常体文字是必要要添加的参数类型,冒号后面告 诉您参数具体应该是什么。
第十节 别名和文件,路径
-
alias objects
一个alias对象的英文一个动态参照现有的文件系统-对象。因为它是动态的,所以即使该对象被移动或重命名,它也可以保持指向其指定的文件系统对象的链接。
Alias就是文件的 一个指针,它指向的某个实际的文件,但Alias本身不是文件(因为它只记录文件的ID), 请特别注意它不同于windows的快捷方式──记录文件的路径!Mac OS的Alias是记录文件的 唯一识别码,即使文件被移动了,Alias替身仍然可以准确指向本来所指的文件。
alias关键词后加上路径 ──text类型的,以冒号为分隔符的完整路径。
-
file objects
file对象表示在所述文件系统-中的特定位置的特定文件。它可以引用当前不存在的项目,例如要创建的文件的名称和位置。一个file对象不是动态的,并始终指向同一个位置,即使不同的项目被移动到那个地方。该POSIX file 伪类的英文粗略的代名词文件:POSIX file符评估的file对象,但它们使用不同的语义的名称,在如指定的路径。file类型多用于操作尚不存在的文件。
Mac系统中,常用的文件路径有两种,一种是完整路径,即以冒号分隔的;另一种是POSIX路径,以斜杠 (/)分隔。AppleScript默认使用前者。 - 绝对路径alias
AppleScript中提供的相对路径 path to命令就是用来解决绝对路径alias这个问题。 - POSIX路径
它具有简明性和相对性的特点,也可以用来避免绝对路径的致命缺陷。
POSIX path of 命令用于获得POSIX格式的路径。
POSIX file是一个类型+POSIX路径 -> 路径是文件或文件夹本身的存储位置的路径。
第十一节 循环语句
* repeat X times(类似于for循环)
repeat 重复的次数 times
end repeat
* repeat from to by
by递增数部分可以缺省,如果缺省了那么每次计数变量加1。
repeat with 计数变量 from 初始值 to 目标值 by 递增数
end repeat
* repeat in
类似于for in循环的语句,可以用来遍历列表
<pre>set aList to {1, 2, 3}
repeat with anItem in aList
display dialog anItem as string
end repeat</pre>
repeat until
<pre>repeat until 条件
...
end repeat</pre>repeat while
类似于while循环
repeat while 条件
end repeat
第十二节 基本用户交互
AppleScript中基本的用户交互──主要是对话框。在开始具体内容之前, 有必要说明一点:常规的AppleScript脚本并不包含用户界面(UI),因此本章介绍的用户交 互其实都是简单的对话框或者系统面板15。AppleScript自带的用户交互功能全部包括于 AppleScript字典中Standard Addition下User Interaction类。
Display Dialog命令
带有输入框的对话框
带有输入框的对话框
列表选择对话框
文件选择对话框
第十三节 错误处理
涉及的命令是Standard Addition类中的
基本语法
-
AppleScript和对象
编写,编译和执行脚本时,使用的所有内容都是一个对象。一个对象是一个类的定义,其可包括属性和动作的实例化。AppleScript为最常使用的对象定义类,从顶层script对象开始,这是正在使用的整体脚本。在一个script对象中,可以使用其他对象,包括:
1.AppleScript对象:
AppleScript为布尔值,脚本,文本,数字和其他类型的对象定义类,用于在脚本中工作; 有关完整列表,请参阅类参考。
2.macOS对象:
macOS和它分布的应用程序的脚本部分,如Finder,系统事件和数据库事件(位于/System/Library/CoreServices
)定义了许多有用的类。
3.应用对象:
第三方脚本化应用程序定义支持各种功能的类。
* 脚本对象
当您在脚本编辑器中的脚本窗口中输入AppleScript语句时,您正在使用顶级script对象。所有script对象定义遵循相同的语法,除了顶级script对象没有标记其开始和结束的语句。
(可选):属性是一个标记的容器,用于存储值、一个run处理程序包含的语句是运行脚本时的AppleScript执行、隐式run处理程序由任何包含的处理程序或script对象之外的任何语句组成、处理程序等同于子例程、一个script对象可以包含嵌套script对象,每个对象的定义就像一个顶级script对象,除了一个嵌套script对象用标记其开始和结尾的语句括起来。(有关详细信息,请参阅脚本对象。)
以下是一个具有一个属性,一个处理程序,一个嵌套script对象以及一个run含有两个语句的隐式处理程序的简单脚本的示例:
<pre>
property defaultClientName : "Mary Smith"
on greetClient(nameOfClient)
display dialog ("Hello " & nameOfClient & "!")
end greetClient
script testGreet
greetClient(defaultClientName)
end script
run testGreet --result: "Hello Mary Smith!"
greetClient("Joe Jones") --result: "Hello Joe Jones!"
</pre>
* 对于script该类,AppleScript允许您定义其他属性。
* 元素
一个元素是包含在另一对象中的一个对象。 任何AppleScript类的定义都包含可以包含的元素类型。对象通常可以包含其每个元素的零个或多个。
-
命令类型
用tell告诉应用程序怎么做,记得用end tell结束这个过程。
<pre>tell application"Finder"
display dialog theString&theAnswer
end tell</pre>Apple提供的标准添加的脚本添加命令,作为macOS的一部分。这些命令可用于所有脚本
脚本编辑器中检查其字典来确定应用程序支持哪些命令。
-
对象说明符
对象说明符描述对象类型,位置以及如何将对象与该位置中相同类型的其他对象区分开来。对象说明符可以引用诸如窗口或文件的应用程序对象或AppleScript对象,例如列表中的项目或记录中的属性。应用程序通常返回对象说明符以响应命令。
tell application "TextEdit"
--paragraph 1 of text of document 1
paragraph 1 of document 1
end tell
在这个例子中,tell语句提供了顶级的容器of application "TextEdit"。容器是短语of document 1(容器是一个包含一个或多个对象或属性的对象。在对象说明符中,容器指定在何处查找对象或属性。要指定容器,请使用单词of或in,也可以使用占有式form('s)来指定容器)。属性短语of text(已省)。对象的类是paragraph,区别信息是类paragraph和索引值的组合1,它们一起表示第一段。
-
变量
局部变量:只在一个对象内部有效(可访问和修改),在其他对象里没法访问
全局变量:只要在同一个脚本(脚本包)内,任何对象都能访问(和/或修改)的。
在不指定全局或局部时,变量默认都为局部变量
强制全局或者局部:
在定义变量之前,增加“Global name”(全局)或者“Local name”(局部)语句 可以强制控制变量的生存空间,其中name为变量名称。
-
事件处理器(Handler)
相当于其他语言中的方法或者函数。它可以拥有形式参数。 以“on handlerName”开始,以“end handlerName”结束。
-
数据共享机制
在复制和修改时──尤其是通过语句“set b to a”(把变量 b赋值为变量a的值)方式时,对于除了Record和List之外 的基本数据类型,用得都是这样的“拷贝”方式。而不是共享一个数据。以后修改a和b的值,将互不影响。
Record和List的数据共享机制:共享一个数据。(共享数据,只增加引用参考
(Reference))
copy关键字:
要List和Record数据交换方式和其他数据一样,那么您需要将“set”改
为“copy”,需要注意,copy和set中的源数据和目标数据的位置是相反的,并且copy的目标 数据必须要事先定义。
-
属性
定义属性的语句如下:
property Label : value
属性的引用和修改方法和变量是一致的,比如set用来赋值。
属性和变量的区别:
属性的特点1是没有全局和局部之分,所有属性都是全局的。
属性和变量的根本区别在于其稳固性(Consistence)。所谓稳固性,即脚本退出后其 值是否保持不变。属性在脚本退出运行后,仍然记录下它最后的值,并且下一次运行时可以 被调出。因此,属性的一个用途就是记录一个脚本运行了多少次,代码如下:
<pre>
property countTimes : 0
set countTimes to countTimes + 1
display dialog countTimes</pre>
重新编译则清空。
本质上,属性值最终是写入文件,而变量是在内存中的。
-
预定义变量
有些变量是预定义的,它包含预设值(常数)或者可以实现特殊功能。几个常用的预定义变量:
result:记录最近一个命令执行的结果,如果命令没有结果,那么将会得到错误
it:指代最近的一个tell对象
me:这指代段脚本。用法举例path to me返回本脚本所在绝对路径
tab:用于string,一个制表位
return:用于string,一个换行
连续字符
display dialog "This is just a test." buttons {"Great", "OK"} ¬
default button "OK" giving up after 3
您可以将语句扩展到下一行,并将其结束连续字符,¬。 使用美式键盘,您可以通过键入Option-l(小写L)来输入此字符。在脚本编辑器中,您可以键入Option-Return,该选项插入连续字符并将插入点移动到下一行。