【问题标题】:Find and replace several instances in text files using AppleScript使用 AppleScript 查找和替换文本文件中的多个实例
【发布时间】:2021-07-26 03:52:28
【问题描述】:

我完全没有编码或任何知识。但在日常生活中,我必须在 Mac 的 TextEdit 中打开一个文件才能打开一个 .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 件事。我怎样才能以一种不“替换那个”被“用这个”替换的方式来调整这个代码,但是例如“成熟的苹果”是“未成熟的苹果”,“成熟的猕猴桃”是“未成熟的猕猴桃”,“成熟的香蕉”是“未成熟的香蕉”?

我一直对此感到困惑,可能答案比预期的要容易得多,因为我是个菜鸟,我还没有找到解决方案。

非常欢迎您提出这方面的想法。非常感谢!

【问题讨论】:

    标签: file text replace find applescript


    【解决方案1】:

    示例 AppleScript 代码,如下所示,在 ma​​cOS Catalina 下的 Script Editor 中进行了测试系统偏好设置 中的 语言和地区 设置设置为 英语(美国)- 主要 并且为我工作没有问题 1.

    • 1 假设 系统偏好设置 > 安全和隐私 > 隐私中的必要和适当的设置已设置/根据需要解决。

    示例 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 支持文档中的 处理程序 已修改为处理 POSIXHFS+ 文件路径.

    findAndReplaceInText(theText, theSearchString, theReplacementString) 处理程序 if from 在字符串中查找和替换文本 from:Manipulating Text

    如果您需要区分大小写的查找/替换,请取消注释 on findAndReplaceInText(theText, theSearchString, theReplacementString) handlercode--considering case--end considering 行。

    如果您要在编辑之前自动制作文件的备份副本,请从以下代码_行前面删除--

    tell application "Finder" to duplicate file theFile with exact copy
    

    注意:示例 AppleScript 代码 就是这样,没有任何包含的错误处理不包含任何适当的额外错误处理。用户有责任根据需要或需要添加任何错误处理。查看AppleScript Language Guide 中的try statementerror statement。另请参阅Working with Errors。此外,在适当的情况下,可能需要在事件之间使用delay 命令,例如delay 0.5延迟设置得当。

    【讨论】:

    • 您好 user3439894,感谢您的快速回复!我已经测试了你的脚本,它可以工作,所以我比我能表达的更感激!我只需要知道一件事就可以在实践中使用它。我必须做的替换之一是替换 HTML URL。脚本似乎不喜欢诸如“或/”之类的符号。我怎样才能使它适用于具有特殊字符的 URL 和文本,例如将 stackoverflow.com">Visit Stack Overflow 更改为 anyurl.com">Visit something different (不是部分而是作为一个整体)?
    • @vegan_enchilada,您在 OP 中提供的 examples文本文件 中的 纯文本,而不是 HTML(超文本标记语言),因此超出了您提出的原始问题的范围。您应该发布另一个问题,其中包含之前和之后的适当示例等。请查看How to create a Minimal, Reproducible ExampleHow do I ask a good question?HTML 虽然是 text,但在解析时不被视为 文本文件
    • 您好 user3439894。你是绝对正确的。我没有好好考虑这一点。但是,更改 URL 和 URL 文本就像一个魅力。非常感谢! ?
    • @vegan_enchilada,您是否已确定如何使用 example AppleScript code 还是需要一些额外的帮助用那个?
    • 嗨 user3439894,我知道如何使用这个 AppleScript。感谢您的帮助。
    【解决方案2】:

    这是一个不同的 AppleScript 解决方案,它应该可以为您提供您正在寻找的相同结果。它将在您选择的文件中将每个“未成熟”实例替换为“成熟”,并将这些更改直接应用并保存到您的文件中。

    我添加了一点“故障安全”并创建了原始文件的备份,并添加了文件扩展名“bak”(以防万一你搞砸了,所有的地狱都崩溃了,你需要恢复)。

    我在末尾添加的g 选项代表“全局”(文本替换发生在整个文档中,而不仅仅是第一个实例)。

    请确保 textToReplacereplacementText 属性中的项目数量相同。

    property textToReplace : {"unripe", "word2", "moore text", "<a href=\"stackoverflow.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
    

    这是原始文本的“之前和之后”屏幕截图,然后是替换后的文本。

    【讨论】:

    • RE:“它将用“成熟”替换每个“未成熟”实例,” - 我不得不说我严重怀疑 OP 想要的实际 wordripe 替换 unripe。我相信 examples 其中只有 placeholder 用于实际 word(s) 和或 phase(s) 和实际上有不止一个 word(s) 和或 phase(s),而且它们明显不同。如果是这种情况,那么当前编写的sed command 不会涵盖多个明显不同的 word(s) 和或 phase(s).
    • 我相信我所做的修改将解决您指出的问题。
    猜你喜欢
    • 2014-01-14
    • 1970-01-01
    • 2011-07-29
    • 2013-01-29
    • 2014-08-22
    • 2013-12-26
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    相关资源
    最近更新 更多