循环浏览列表以进行查找和替换
Cycle through a list to do Find & Replace
在我的脚本中,字符串通常少于 200 个字。
theFindList 和 replaceWithList 每个都有 78 个术语...从第一个列表中查找每个术语的每个匹配项,并将其替换为第二个列表中的相应术语。
脚本运行良好,但在重复循环中执行 78 个不同的 do shell 脚本调用中的 sed 命令速度很慢。
如果所有内容都传递给 shell 以便在那里完成迭代,那会更快。我怎么做?
这是 applescript 中现在的相关重复部分。我会将它放入 Automator,这样我可以在 "run shell script" 操作中做的事情就可以了。我可以在一串制表符分隔的数据中查找和替换列表。查找和替换列表是常量,因此需要将它们烘焙到 shell 脚本中,并且只需要从上一个操作接收字符串。
set theString to "foo 1.0 is better than foo 2.0. The fee 5 is the best."
set toFindList to {"foo", "fee", "fo", "fum"}
set replaceWith to {"bar", "bee", "bo", "bum"}
set cf to count of toFindList
-- replace each occurrence of the word followed by a space and a digit
repeat with n from 1 to cf
set toFindThis to item n of toFindList
set replaceWithThis to item n of replaceWithList
set scriptText to "echo " & quoted form of theString & " | sed -e 's/" & toFindThis & " \([0-9]\)/" & replaceWithThis & " \1/'g"
set theString to do shell script scriptText
end repeat
return theString
好的,使用 sed -f 命令文件技术,我让它工作了。该脚本采用制表符分隔的字符串或文件,然后从中构建一个 sed 命令文件。
property theString: "foo 1.0 is better than foo 2.0. The fee 5 is the best."
property substitutionList : "foo bar
fee bee
fo bo
bum bum" -- this tab delim list will have 78 terms
set tabReplace to "\( [0-9]\)/"
set paragraphReplace to "\1/g
s/"
-- parse the replace string into lists
set commandString to ""
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to tab
set commandString to text items of substitutionList
set AppleScript's text item delimiters to tabReplace
set commandString to "s/" & commandString as string
set AppleScript's text item delimiters to return
set commandString to text items of commandString
set AppleScript's text item delimiters to paragraphReplace
set commandString to (commandString as string) & "\1/g"
set AppleScript's text item delimiters to otid
set commandFilePath to ((path to temporary items from user domain) as text) & "commandFile.sed"
try
set fileRef to open for access file commandFilePath with write permission
set eof of fileRef to 0
write commandString to fileRef
close access fileRef
on error
close access fileRef
end try
set posixPath to POSIX path of file commandFilePath
set scriptText to "echo " & quoted form of theString & " | sed -f " & quoted form of posixPath
set theString to do shell script scriptText
return theString
在我的脚本中,字符串通常少于 200 个字。 theFindList 和 replaceWithList 每个都有 78 个术语...从第一个列表中查找每个术语的每个匹配项,并将其替换为第二个列表中的相应术语。 脚本运行良好,但在重复循环中执行 78 个不同的 do shell 脚本调用中的 sed 命令速度很慢。 如果所有内容都传递给 shell 以便在那里完成迭代,那会更快。我怎么做? 这是 applescript 中现在的相关重复部分。我会将它放入 Automator,这样我可以在 "run shell script" 操作中做的事情就可以了。我可以在一串制表符分隔的数据中查找和替换列表。查找和替换列表是常量,因此需要将它们烘焙到 shell 脚本中,并且只需要从上一个操作接收字符串。
set theString to "foo 1.0 is better than foo 2.0. The fee 5 is the best."
set toFindList to {"foo", "fee", "fo", "fum"}
set replaceWith to {"bar", "bee", "bo", "bum"}
set cf to count of toFindList
-- replace each occurrence of the word followed by a space and a digit
repeat with n from 1 to cf
set toFindThis to item n of toFindList
set replaceWithThis to item n of replaceWithList
set scriptText to "echo " & quoted form of theString & " | sed -e 's/" & toFindThis & " \([0-9]\)/" & replaceWithThis & " \1/'g"
set theString to do shell script scriptText
end repeat
return theString
好的,使用 sed -f 命令文件技术,我让它工作了。该脚本采用制表符分隔的字符串或文件,然后从中构建一个 sed 命令文件。
property theString: "foo 1.0 is better than foo 2.0. The fee 5 is the best."
property substitutionList : "foo bar
fee bee
fo bo
bum bum" -- this tab delim list will have 78 terms
set tabReplace to "\( [0-9]\)/"
set paragraphReplace to "\1/g
s/"
-- parse the replace string into lists
set commandString to ""
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to tab
set commandString to text items of substitutionList
set AppleScript's text item delimiters to tabReplace
set commandString to "s/" & commandString as string
set AppleScript's text item delimiters to return
set commandString to text items of commandString
set AppleScript's text item delimiters to paragraphReplace
set commandString to (commandString as string) & "\1/g"
set AppleScript's text item delimiters to otid
set commandFilePath to ((path to temporary items from user domain) as text) & "commandFile.sed"
try
set fileRef to open for access file commandFilePath with write permission
set eof of fileRef to 0
write commandString to fileRef
close access fileRef
on error
close access fileRef
end try
set posixPath to POSIX path of file commandFilePath
set scriptText to "echo " & quoted form of theString & " | sed -f " & quoted form of posixPath
set theString to do shell script scriptText
return theString