我编写了一个脚本,该脚本可以在我管理的网站上自动创建产品。在我的过程中,我上传产品的JPEG图像,并提取JPEG中标记的关键字以添加到产品信息中。在此过程中,我使用Applescript激活Safari并处理Javascript代码行。代码行包含一个从Applescript Shell脚本派生的变量。
下面的代码
tell application "Finder"
set sourceFolder to folder POSIX file "/Users/<username>/Desktop/Upload/Temp/HighRes/"
set theFiles to files of sourceFolder
set inputPath to "/Users/<username>/Desktop/Upload/Temp/"
end tell
repeat with afile in theFiles
set filename to name of afile
set fname to text 1 thru ((offset of "." in filename) - 1) of filename
--INPUT CODE TO BE LOOPED OVER BELOW--
--Add Image Keywords from Metadata--
try
set pathVAR1 to "/Users/<username>/Desktop/Upload/Temp/HighRes/"
set pathVAR2 to pathVAR1 & filename
set myvar to do shell script "mdls -name kMDItemKeywords " & quoted form of pathVAR2
set var1 to ((offset of "(" in myvar) + 1)
set var2 to ((length of myvar) - 1)
set myKeywords to ((characters var1 thru var2 of myvar) as string)
--Inputs the Keywords from the Image Metadata--
tell application "Safari"
activate
do JavaScript "document.getElementById('ctl00_cphMainContent_txtKeyWords').value = \"" & myKeywords & "\";" in current tab of window 1
end tell
end try
--END OF CODE TO BE LOOPED OVER--
end repeat
==结束代码==
问题:
下面的代码没有将变量myKeywords传递给Safari,但是如果我运行一个对话框,它将出现在对话框中。
do JavaScript "document.getElementById('ctl00_cphMainContent_txtKeyWords').value = \"" & myKeywords & "\";" in current tab of window 1
答案 0 :(得分:1)
我尝试了CJK建议的反引号(`),但对我来说不起作用。提出的主要问题是kMDItemKeywords返回了转义字符。
Heart,
Studio,
Red,
\"RF126-10.tif\",
Tree,
\"Heart Tree\",
occasion,
Farm,
birds,
\"Red Farm Studio\",
\"all occasion\",
all
我可以使用以下方法摆脱转义字符:
新代码
set myKeywords to do shell script "echo " & quoted form of myKeywords & " | tr -d '[:cntrl:]'| tr '[:upper:]' '[:lower:]' | tr -d '\"'"
JAVASCRIPT的更新代码
--Inputs the Keywords from the Image Metadata--
tell application "Safari"
activate
do JavaScript "document.getElementById('ctl00_cphMainContent_txtKeyWords').value = '" & myKeywords & "';" in current tab of window 1
end tell
结果
--> " heart, studio, red, rf126-10.tif, tree, heart tree, occasion, farm, birds, red farm studio, all occasion, all"
答案 1 :(得分:0)
我没有一个绝对可以解决您问题的特定解决方案,但是我对您的脚本有很多观察,并提出了有关如何更改脚本以提高其速度,健壮性和遵循最佳实践原则的建议。
摆脱掉try
块。如果用不必要的错误捕获掩盖错误,那么当事情出错时,您不知道脚本中正在发生什么。 try...end try
中唯一需要包含的行是do shell script
,但是只有在知道代码可以正常工作时才将其放入。通常,仅应使用try
块:
try
块不再用于强制脚本在未知原因的不便错误后继续执行,但是有一个清晰且定义明确的函数,可以与您的代码和谐地执行,而不是违反代码。作为AppleScript中的一般规则,如果可以避免,请勿使用 Finder 来执行文件系统操作:它很慢,并且在执行操作时会阻塞,这意味着您可以在此期间不与GUI交互。请改用系统事件。它是一个无面子的应用程序,在执行任务时不会停止其他操作。特别是在AppleScript和 Finder 的情况下,它速度很快,并且不像 Finder 那样容易超时。它本机处理posix路径(波浪号的包括扩展),而无需使用POSIX file
进行任何强制转换;它返回alias
对象,这是每个其他可编写脚本的应用程序都可以理解的文件对象的通用类。
在某些情况下,仍然需要 Finder 。 系统事件不能reveal
文件;也无法在 Finder 中获取当前选择的文件。但是,让 Finder 以selection
的形式获取alias list
,然后切换到系统事件来对该列表进行实际的文件处理就足够了
这很好奇:
set filename to name of afile
set fname to text 1 thru ((offset of "." in filename) - 1) of filename
我是否正确地认为fname
打算仅保留文件名的基本文件名部分,并且此操作旨在删除扩展名?这是一个很好的第一次尝试,并且在这里使用text
逐项列出字符串的组成部分而不是characters
时做得很好。但是,如果文件名中包含多个"."
,那么它当然会砍掉比文件扩展名更多的东西,这并不罕见。
一种安全地cast割文件名末尾的方法是使用text item delimiters
:
set filename to the name of afile
set fname to the filename
set my text item delimiters to "."
if "." is in the filename then set fname to text items 1 thru -2 of the filename as text
然后应该注意或重置text item delimiters
,否则稍后尝试将字符串连接在一起时会产生后果。
不使用text item delimiters
的情况下扩展扩展的另一种方法是字符串扫描,这是您在执行操作或测试时迭代字符串的字符并获得所需结果的方法。它比听起来快,并且是用于非常复杂的字符串搜索和操作的强大技术:
set filename to the name of afile
set fname to the filename
repeat while the last character of fname ≠ "."
set fname to text 1 thru -2 of fname
end
set fname to text 1 thru -2 of fname
您还可以检索文件的name extension
属性,获取文件的长度,并从文件名末尾删除(1 + that)
个字符。有多种方法可以达到相同的结果。
在特定情况下这是错误的:
set myKeywords to ((characters var1 thru var2 of myvar) as string)
characters
产生一个list
,然后您必须将其连接回一个string
,如果不确定是否设置了text item delimiters
,这是不安全的至。由于您没有在脚本中对其进行引用,因此应将其 设置为空字符串,这将导致字符重新组合成单词,从而产生预期的结果。但是,如果您执行了文件扩展名cast割的第一种技术而忽略了将text item limiters
设置回去的情况,那么情况就很容易发生,那么结果字符串将在每个字母之间都有一个句点。>
作为AppleScript中的一项政策(您可以选择坚持还是忽略),如果您先执行列表设置字符串强制操作 而未设置这些字符串,则将其视为劣质形式,请先设置{{1 }}确定的值。
但是您不必在这里这样做,因为与其使用text item delimiters
,还不如使用characters
:
text
您正在执行如下所示的shell命令:set myKeywords to text var1 thru var2 of myvar
,然后笨拙地跟随AppleScript的两行尝试在bash的文本表示形式周围剪掉前后括号。数组。相反,您可以打开mdls -name kMDItemKeywords <file>
的{{1}}标志,通过为您剥离密钥名称来简化输出。然后,将括号作为第一个和最后一个字符。但是,由于在输出中也有大量空白字符,您不妨让bash为您执行所有清理工作:
-raw
这不考虑括号,双引号,逗号和空格,因此您得到的只是一个关键字列表,每行一个,并且没有任何多余的负担。如果需要逐项列出,则可以将变量设置为mdls
命令的输出mdls -raw -name kMDItemContentTypeTree <file> | grep -E -io '[^()",[:blank:]]+'
,该命令将文本分成几行,将每个关键字放入列表中。但是似乎在这里您需要文本,并且不介意它是多线性的。
当我开始写这个答案时,我对导致您到达这里的特定问题的原因并没有什么了解。详细介绍了the paragraphs of
的输出格式后,现在看到的问题是do shell script
字符串将包含一串双引号,并且您已经将{ JavaScript表达式中的mdls
实体带有双引号。所有这些引号在AppleScript环境中仅被均等地转义一次,而在JavaScript环境中仅被一次转义,这导致每个相邻的双引号都充当开/闭对。我在bash中运行了类似的命令以获取值数组(myKeywords
),然后以AppleScript的方式处理文本,然后在浏览器中打开JavaScript控制台并粘贴以说明发生了什么:< / p>
字符串中包含红色的任何内容;因此,其他所有内容都将用作JavaScript标识符或对象(或者如果弄乱的引号也不会弄乱语法,则将导致未终止的字符串,该字符串仍希望最后一个引号与之配对。
我认为解决方案是使用连续字符myKeywords
,以实现与旧版浏览器的向后兼容性:因此,您需要在每行(最后一行除外)的后面加上反斜杠 并且 ,您需要将JavaScript表达式中kMDContentTreeType
值周围的双引号对更改为一对单引号。在较新的浏览器中,您可以不必在每行上添加连续标记,而将一对外部双引号替换为一对反引号("\"
):
myKeywords