在Applescript中替换某些大文本文件行的快速方法

时间:2014-12-11 15:10:32

标签: string replace applescript registry large-files

我有一个大的注册表文件(30,000多行),我希望能够使用Applescript更改两行。我目前的代码需要几分钟才能完成;我希望有一种方法可以将其减少到2秒或更短。有没有办法做到这一点?

这两行之前是格式化的(我想更改端口和地址行的值):

[path\that\always\stays\the\same] <# that isn't always the same>  
"Address"="<# that isn't always the same>"
"Port"="<# that isn't always the same>"

以下是我目前的代码改编自this thread at MacScripter

set theFile to (((theAppResourcesFolder) as text) & "system.reg") as alias
set N to open for access theFile with write permission
get eof N
if result > 0 then
    set theText to read N
    set eof N to 0
    write deleteLinesFromText(theText, "\"Address\"", "\"Port\"", finalResultAddress, finalResultPort) to N

    --close theFile
end if
close access N

这是deleteLinesFromText:

on deleteLinesFromText(theText, deletePhrase1, deletePhrase2, newPhrase1, newPhrase2)
set newText to ""
try
    set textList to paragraphs of theText
    repeat with i from 1 to count of textList
        set thisLine to item i of textList
        if thisLine contains deletePhrase1 then
            set newText to newText & "\"Address\"=\"" & newPhrase1 & "\"" & return
        else if thisLine contains deletePhrase2 then
            set newText to newText & "\"Port\"=\"" & newPhrase2 & "\"" & return
        else
            set newText to newText & thisLine & return
        end if
    end repeat
    if newText is not "" then set newText to text 1 thru -2 of newText

end try
return newText
end deleteLinesFromText

2 个答案:

答案 0 :(得分:2)

AppleScript中的文字是一个整体。按行处理文件没有任何好处,但有时可以使代码更容易理解。它与搜索和替换的过程相同,但现在您的整个匹配基于两个匹配项以及介于两者之间的所有文本。正确设置文本项分隔符时,您可以摆脱整个循环:

set theText to "Fake text fake text fake text
\"Address\"=blah blah blah
fake text fake text fake text fake text
\"Port\"=305
fake text fake text fake text"

deleteLinesFromText(theText, "\"Address\"", "\"Port\"", "http://stackoverflow.com", 80)

on deleteLinesFromText(theText, deletePhrase1, deletePhrase2, newPhrase1, newPhrase2)
    set oldTIDs to AppleScript's text item delimiters
    set newAddress to "\"Address\"=" & newPhrase1
    set newPort to "\"Port\"=" & newPhrase2

    set AppleScript's text item delimiters to deletePhrase1
    set oldAddress to {""} & first paragraph of text item 2 of theText as string
    set AppleScript's text item delimiters to oldAddress
    set textItems to every text item of theText
    set AppleScript's text item delimiters to newAddress
    set theText to textItems as string
    set AppleScript's text item delimiters to deletePhrase2
    set oldPort to {""} & first paragraph of text item 2 of theText as string
    set AppleScript's text item delimiters to oldPort
    set textItems to every text item of theText
    set AppleScript's text item delimiters to newPort
    set theText to textItems as string

    set AppleScript's text item delimiters to oldTIDs
    return theText
end deleteLinesFromText

答案 1 :(得分:1)

虽然sed可能会更快,但这可能会浪费一段时间......

set newText to ""
set paraList to paragraphs of theText
repeat with thisLine in my paraList

    if thisLine contains deletePhrase1 then
        set newText to newText & "\"Address\"=\"" & newPhrase1 & "\"" & return
    else if thisLine contains deletePhrase2 then
        set newText to newText & "\"Port\"=\"" & newPhrase2 & "\"" & return
    else
        set newText to newText & thisLine & return
    end if
end repeat
if newText is not "" then set newText to text 1 thru -2 of newText
return newText