使用 AppleScript 在文本文件中查找和替换多个实例
Find and replace several instances in text files using AppleScript
我对编码一无所知。但是在日常生活中,我必须在 TextEdit 中打开一个文件 Mac 来打开一个 .txt 文件并查找并替换几个文本实例。不难,但是如果有一个自动化的解决方案就太好了(节省时间并避免人为错误)。
在这个网站上,我找到了 this interesting script by dj bazzie wazzie,而且我什至可以使用 Automator 让它工作,所以很有希望!
set stringToFind to "replace that"
set stringToReplace to "with this"
set theFile to choose file
set theContent to read theFile as «class utf8»
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, stringToFind}
set ti to every text item of theContent
set AppleScript's text item delimiters to stringToReplace
set newContent to ti as string
set AppleScript's text item delimiters to oldTID
try
set fd to open for access theFile with write permission
set eof of fd to 0
write newContent to fd as «class utf8»
close access fd
on error
close access theFile
end try
但是,我需要更改的不是文件中的 1 个,而是 3 个。我怎样才能以一种不是“替换那个”被替换为“用这个”而是例如“生苹果”变“熟苹果”,“生猕猴桃”变“熟猕猴桃”,“生香蕉”变“熟香蕉”?
一直在纠结这个问题,大概答案比想象的简单多了,因为我是菜鸟,所以一直没有找到答案。
非常欢迎对此提出想法。非常感谢!
示例 AppleScript 代码,如下所示,在[=61= macOS Catalina 下的 ]Script Editor 以及 System Preferences 中的 Language & Region 设置到 英语(美国)— 小学 并为我工作没有问题1.
- 1 假定在 系统偏好设置 > 安全和隐私 > 隐私 已根据需要 set/addressed。
示例 AppleScript 代码:
set textToFindList to {"unripe apple", "unripe kiwi", "unripe banana"}
set textToReplaceWithList to {"ripe apple", "ripe kiwi", "ripe banana"}
if (length of textToFindList) is not equal to ¬
(length of textToReplaceWithList) then return
set theFile to choose file
-- tell application "Finder" to duplicate file theFile with exact copy
set theText to read theFile as «class utf8»
repeat with i from 1 to length of textToFindList
set theText to my findAndReplaceInText(theText, ¬
item i of textToFindList, ¬
item i of textToReplaceWithList)
end repeat
my writeToFile(theText, theFile, true)
-- # Handlers #
on findAndReplaceInText(theText, theSearchString, theReplacementString)
--considering case
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
set AppleScript's text item delimiters to ""
return theText
--end considering
end findAndReplaceInText
on writeToFile(theText, theFile, overwriteExistingContent)
try
set theFile to theFile as string
if theFile contains "/" then
set theOpenedFile to open for access theFile with write permission
else
set theOpenedFile to open for access file theFile with write permission
end if
if overwriteExistingContent is true then set eof of theOpenedFile to 0
write theText to theOpenedFile starting at eof
close access theOpenedFile
return true
on error
try
close access file theFile
end try
return false
end try
end writeToFile
备注:
writeToFile(theText, theFile, overwriteExistingContent)
handler 是对 handler 的略微修改,来自:Reading and Writing Files
链接的 Apple 支持文档中的 handler 已修改为同时处理 POSIX 和 HFS+ 文件路径.
findAndReplaceInText(theText, theSearchString, theReplacementString)
处理程序 if from Finding and Replacing Text in a String from: Manipulating Text
如果您需要区分大小写 find/replace 然后取消注释 on findAndReplaceInText(theText, theSearchString, theReplacementString)
中 code 的 --considering case
和 --end considering
行 处理程序.
如果您要在编辑 文件 之前自动制作备份副本,请从 [=] 的以下行前面删除 --
40=]代码_:
tell application "Finder" to duplicate file theFile with exact copy
注意:示例 AppleScript code 就是这样,没有包含任何 错误处理 不包含任何额外的 错误处理 可能是适当的。用户有责任根据需要或需要添加任何 错误处理 。查看 try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay 命令 在适当的事件之间可能是必要的,例如delay 0.5
,适当设置延迟的值。
这是一个不同的 AppleScript 解决方案,它应该会为您提供与您正在寻找的相同的结果。它将在您选择的文件中将“未成熟”的每个实例替换为“成熟”,并将这些更改直接应用并保存到您的文件中。
我添加了一点“故障安全”并创建了原始文件的备份,添加了文件扩展名“bak”(以防万一你搞砸了,一切都崩溃了,你需要恢复原状) .
我在最后添加的 g
选项代表“全局”(文本替换发生在整个文档中,而不仅仅是第一个实例)。
请确保 textToReplace
和 replacementText
属性中的项目数量相同。
property textToReplace : {"unripe", "word2", "moore text", "<a href=\"whosebug.com\">Visit Stack Overflow</a>", "delete this phrase"}
property replacementText : {"ripe", "Word Two", "More Text", "<a href=\"anyurl.com\">Visit something different</a>", ""}
activate
set theFile to quoted form of POSIX path of (choose file)
do shell script "cp " & theFile & " " & theFile & ".bak"
repeat with i from 1 to count of textToReplace
do shell script "sed -i '' 's|" & (item i of textToReplace) & ¬
"|" & (item i of replacementText) & "|g' " & theFile
end repeat
这是原文和替换后文本的“前后”截图。
我对编码一无所知。但是在日常生活中,我必须在 TextEdit 中打开一个文件 Mac 来打开一个 .txt 文件并查找并替换几个文本实例。不难,但是如果有一个自动化的解决方案就太好了(节省时间并避免人为错误)。
在这个网站上,我找到了 this interesting script by dj bazzie wazzie,而且我什至可以使用 Automator 让它工作,所以很有希望!
set stringToFind to "replace that"
set stringToReplace to "with this"
set theFile to choose file
set theContent to read theFile as «class utf8»
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, stringToFind}
set ti to every text item of theContent
set AppleScript's text item delimiters to stringToReplace
set newContent to ti as string
set AppleScript's text item delimiters to oldTID
try
set fd to open for access theFile with write permission
set eof of fd to 0
write newContent to fd as «class utf8»
close access fd
on error
close access theFile
end try
但是,我需要更改的不是文件中的 1 个,而是 3 个。我怎样才能以一种不是“替换那个”被替换为“用这个”而是例如“生苹果”变“熟苹果”,“生猕猴桃”变“熟猕猴桃”,“生香蕉”变“熟香蕉”?
一直在纠结这个问题,大概答案比想象的简单多了,因为我是菜鸟,所以一直没有找到答案。
非常欢迎对此提出想法。非常感谢!
示例 AppleScript 代码,如下所示,在[=61= macOS Catalina 下的 ]Script Editor 以及 System Preferences 中的 Language & Region 设置到 英语(美国)— 小学 并为我工作没有问题1.
- 1 假定在 系统偏好设置 > 安全和隐私 > 隐私 已根据需要 set/addressed。
示例 AppleScript 代码:
set textToFindList to {"unripe apple", "unripe kiwi", "unripe banana"}
set textToReplaceWithList to {"ripe apple", "ripe kiwi", "ripe banana"}
if (length of textToFindList) is not equal to ¬
(length of textToReplaceWithList) then return
set theFile to choose file
-- tell application "Finder" to duplicate file theFile with exact copy
set theText to read theFile as «class utf8»
repeat with i from 1 to length of textToFindList
set theText to my findAndReplaceInText(theText, ¬
item i of textToFindList, ¬
item i of textToReplaceWithList)
end repeat
my writeToFile(theText, theFile, true)
-- # Handlers #
on findAndReplaceInText(theText, theSearchString, theReplacementString)
--considering case
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
set AppleScript's text item delimiters to ""
return theText
--end considering
end findAndReplaceInText
on writeToFile(theText, theFile, overwriteExistingContent)
try
set theFile to theFile as string
if theFile contains "/" then
set theOpenedFile to open for access theFile with write permission
else
set theOpenedFile to open for access file theFile with write permission
end if
if overwriteExistingContent is true then set eof of theOpenedFile to 0
write theText to theOpenedFile starting at eof
close access theOpenedFile
return true
on error
try
close access file theFile
end try
return false
end try
end writeToFile
备注:
writeToFile(theText, theFile, overwriteExistingContent)
handler 是对 handler 的略微修改,来自:Reading and Writing Files
链接的 Apple 支持文档中的 handler 已修改为同时处理 POSIX 和 HFS+ 文件路径.
findAndReplaceInText(theText, theSearchString, theReplacementString)
处理程序 if from Finding and Replacing Text in a String from: Manipulating Text
如果您需要区分大小写 find/replace 然后取消注释 on findAndReplaceInText(theText, theSearchString, theReplacementString)
中 code 的 --considering case
和 --end considering
行 处理程序.
如果您要在编辑 文件 之前自动制作备份副本,请从 [=] 的以下行前面删除 --
40=]代码_:
tell application "Finder" to duplicate file theFile with exact copy
注意:示例 AppleScript code 就是这样,没有包含任何 错误处理 不包含任何额外的 错误处理 可能是适当的。用户有责任根据需要或需要添加任何 错误处理 。查看 try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay 命令 在适当的事件之间可能是必要的,例如delay 0.5
,适当设置延迟的值。
这是一个不同的 AppleScript 解决方案,它应该会为您提供与您正在寻找的相同的结果。它将在您选择的文件中将“未成熟”的每个实例替换为“成熟”,并将这些更改直接应用并保存到您的文件中。
我添加了一点“故障安全”并创建了原始文件的备份,添加了文件扩展名“bak”(以防万一你搞砸了,一切都崩溃了,你需要恢复原状) .
我在最后添加的 g
选项代表“全局”(文本替换发生在整个文档中,而不仅仅是第一个实例)。
请确保 textToReplace
和 replacementText
属性中的项目数量相同。
property textToReplace : {"unripe", "word2", "moore text", "<a href=\"whosebug.com\">Visit Stack Overflow</a>", "delete this phrase"}
property replacementText : {"ripe", "Word Two", "More Text", "<a href=\"anyurl.com\">Visit something different</a>", ""}
activate
set theFile to quoted form of POSIX path of (choose file)
do shell script "cp " & theFile & " " & theFile & ".bak"
repeat with i from 1 to count of textToReplace
do shell script "sed -i '' 's|" & (item i of textToReplace) & ¬
"|" & (item i of replacementText) & "|g' " & theFile
end repeat
这是原文和替换后文本的“前后”截图。