Groovy 逐行修改文本文件的脚本

Groovy script to modify text file line by line

我有一个输入文件,Groovy 文件从中读取输入。处理特定输入后,Groovy 脚本应该能够注释它使用的输入行,然后继续。

文件内容:

1   
2        
3

当它处理第 1 行和第 2 行时,输入文件将如下所示:

'1    
'2                   
3

通过这种方式,如果我重新运行 Groovy,我想从上次停止的那行开始。如果使用输入但失败,则不应注释该特定行 (') 以便可以尝试重试。

如果您能帮助起草 Groovy 脚本,我们将不胜感激。

谢谢

AFAIK in Groovy 您只能在文件末尾追加文本。

因此要在处理时在每一行上添加 ',您需要重写整个文件。

您可以使用以下方法,但我只建议您使用小文件,因为您要将所有行加载到内存中。总之,您的问题的方法可能是:

// open the file
def file = new File('/path/to/sample.txt')
// get all lines
def lines = file.readLines()

try{
    // for each line
    lines.eachWithIndex { line,index ->
        // if line not starts with your comment "'"
        if(!line.startsWith("'")){
            // call your process and make your logic...
            // but if it fails you've to throw an exception since
            // you can not use 'break' within a closure
            if(!yourProcess(line)) throw new Exception()

            // line is processed so add the "'"
            // to the current line
            lines.set(index,"'${line}")
        }
     }
}catch(Exception e){
  // you've to catch the exception in order
  // to save the progress in the file
}

// join the lines and rewrite the file
file.text = lines.join(System.properties.'line.separator')

// define your process...
def yourProcess(line){
    // I make a simple condition only to test...
    return line.size() != 3
}

避免为大文件加载内存中所有行的最佳方法是使用 reader 读取文件内容,并使用带有写入器的临时文件写入结果,优化版本可以是:

// open the file
def file = new File('/path/to/sample.txt')

// create the "processed" file
def resultFile = new File('/path/to/sampleProcessed.txt')

try{
    // use a writer to write a result
    resultFile.withWriter { writer ->
        // read the file using a reader 
        file.withReader{ reader ->
            while (line = reader.readLine()) {

                // if line not starts with your comment "'"
                if(!line.startsWith("'")){

                    // call your process and make your logic...
                    // but if it fails you've to throw an exception since
                    // you can not use 'break' within a closure
                    if(!yourProcess(line)) throw new Exception()

                    // line is processed so add the "'"
                    // to the current line, and writeit in the result file
                    writer << "'${line}" << System.properties.'line.separator'
                }    
            }
        }
    }

}catch(Exception e){
  // you've to catch the exception in order
  // to save the progress in the file
}

// define your process...
def yourProcess(line){
    // I make a simple condition only to test...
    return line.size() != 3
}