AppleScript

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图标)。要理解这些东西怎么工作在一起,最好的方法就是用字典来写一个脚本范例。
如何阅读字典(命令):
第一行说明词性和具体解释“创建一个新元素”
之后开始就是完整的命令语句所应该(或者可以)含有的内容:

  1. 体字是关键字,即必须一字不差的照打,如果带有[]则是 可以省略的(可选关键字)。
  2. 在黑体字后面、冒号前面的正常体文字是必要要添加的参数类型,冒号后面告 诉您参数具体应该是什么。

第十节 别名和文件,路径

  • 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类的定义都包含可以包含的元素类型。对象通常可以包含其每个元素的零个或多个。

  • 命令类型

    • 一个AppleScript的命令是一个内置的AppleScript的语言。目前有五个这样的命令:getsetcountcopy,和run。除此之外copy,这些命令也可以由应用程序实现。也就是说,有一个适用于AppleScript对象的AppleScript版本的命令,但应用程序可以定义自己的版本,该版本适用于它定义的对象类型。
    • 定义变量用set ...to...
    • 获取变量用get
      set theSecondNumber to 2
      get theSecondNumber
  • 用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,该选项插入连续字符并将插入点移动到下一行。

AppleScript
链接1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容