Change only the numbers of a line in a file - groovy

I would like to change only the numbers of a line.
Source file:
IMAGE_VERSION_TD_S=1.108.1.1
IMAGE_VERSION_CPO=1.87.13.1
IMAGE_VERSION_CVM=1.71.1.1
I would like to search for a string like ("IMAGE_VERSION_CPO=") and change only the numbers to 1.90.12.1.
Output file:
IMAGE_VERSION_TD_S=1.108.1.1
IMAGE_VERSION_CPO=1.90.12.1
IMAGE_VERSION_CVM=1.71.1.1
I have tried on this way but it generated a new line on the final file:
def data = readFile(file: pathEnv)
def lines = data.readLines()
def strNewEnv = ''
lines.each {
String line ->
if (line.startsWith("IMAGE_VERSION_CPO=")) {
strNewEnv = strNewEnv + '\n' + 'IMAGE_VERSION_CPO=' + imageVersion
} else {
strNewEnv = strNewEnv + '\n' + line
}
println line
}
println strNewEnv
writeFile file: directoryPortal+"/${params.ENVIROMENT}/"+envFile, text: strNewEnv

If this is a properties file, use the readProperties step:
def props = readProperties file: pathEnv, text: "IMAGE_VERSION_CPO=${imageVersion}"
writeFile file: "${directoryPortal}/${params.ENVIROMENT}/${envFile}", text: props.collect { "${it.key}=${it.value}" }.join("\n")
If, for some reason, this isn't a props file:
def data = readFile(file: pathEnv)
data = data.replaceAll(/(?<=IMAGE_VERSION_CPO=)[\d\.]+/, imageVersion)
writeFile file: "${directoryPortal}/${params.ENVIROMENT}/${envFile}", text: data
There's likely a much better regex for that but it seems to be working

Related

How to append a new line to a list in python?

I'm trying to append a new line in a list in python to write to my text file any suggestions?
header = ['Employee ID','Type','Routing Number','Account Number']
header.append("\n")
strOtherLine = [strSsn,strThisType,strThisRoute,strThisAcct]
header.append("\n" + strOtherLine)
fc_otherfile = r"c:\******\*****\gah\\" + strOtherSavedFile
#===Writing to the text file
with open(fc_otherfile,'w', newline='') as t:
dirdep = csv.writer(t, delimiter="\t")
dirdep.writerow(header)
This is what I get in my text file:
Employee ID Type Routing Number Account Number "" ['###########', 'Checking', '###########','###########'] ['###########', 'Checking', '###########', '###########']
But what I want is this:
Employee ID Type Routing Number Account Number
########### Checking ########### ###########
########### Checking ########### ###########
Simply make a string of a list using ' '.join(). Whenever appending line use obj.write('\n') after that.
Example: Using text file.
MyData = ['I', 'am', 'fine']
line1 = ' '.join(MyData)
with open('file.txt', 'a+') as data:
data.write(line1)
data.write('\n')
You're using lists when you should be using strings:
header = 'Employee ID\tType\tRouting Number\tAccount Number'
header += "\n"
strOtherLine = strSsn +'\t'+ strThisType +'\t'+ strThisRoute +'\t'+ strThisAcct
header += "\n"+ strOtherLine
fc_otherfile = r"c:\******\*****\gah\\" + strOtherSavedFile
#===Writing to the text file
with open(fc_otherfile,'w', newline='') as t:
t.write(header)
#confirm write was successful
with open(fc_otherfile,'r') as t2:
print(t2.read())
If you love loops you could try something like this:
toinsert = ""
for each in header:
toinsert.append(str(each)+"\t")
toinsert.rstrip() #remove trailing "\t"
toinsert += "\n"
for each in strOtherLine:
toinsert.append(str(each)+"\t")
toinsert.rstrip()
toinsert += "\n"
with open('file.txt', 'a+') as data:
data.write(toinsert)

Delete row in text file

I'm reading a text file in Groovy:
new File(testprojectDir + '/Testdata///' + filename).withReader('UTF-8') { reader ->
def line
while ((line = reader.readLine()) != null) {
log.info "${line}"
}
}
The text file generates as follows:
123
456
789
My problem Is that I'd like to remove the line I've just red.
Example: 123 will be deleteted after it's been red.
And continue to next row, read that line and remove that line (save the same text file) until the file no longer has rows, that means that the text file is empty (every line is deleted)
How can I do that?
You can use an output file.
def ofile = new File(outputFile)
new File(testprojectDir + '/Testdata///' + filename).withReader('UTF-8') { reader ->
def line
while ((line = reader.readLine()) != null && !line.contains("text i don't want")) {
log.info "${line}"
ofile.append(line)
}
}
If you want to do it in-place:
def fileA = new File("src/file.txt")
List data = fileA.readLines()
fileA.text = ''
data.each { line ->
if (!line.contains("b")) {
log.info "${line}"
fileA.append(line) + "\n"
}
}

appendNode using xmlSlurper in a specific position

I'm gonna include the xml structure below:
#Rao, #tim_yates. The actual xml is:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
I need to include a new Node in . The new XML must be:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>
<Salutation>text</Salutation>
</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
The question is how to append a new node in ?
I've found many samples how to use appendNode, however, it is always a
root.child. I need to go further in my XML structure and append a node at
prnReq.ltrPrnReqs.ltrPrnReq.ltrData
the node to be included is <salutation>
Any comments are welcome.
Below the current code.
Many thanks!
import groovy.xml.QName
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
File doc = new File("C:/Temp/letter_.xml")
def prnReq = new XmlSlurper().parse(doc)
prnReq.ltrPrnReqs.ltrPrnReq.each {
def encodedString = it.ltrData.toString()
Base64.Decoder decoder = Base64.getMimeDecoder()
byte[] decodedByteArray = decoder.decode(encodedString)
def output = new String(decodedByteArray)
println output
output.splitEachLine(';') { items ->
println "raSalutation: " + items[0]
println "raFromAcc: " + items[1]
println "raPayableTo: " + items[2]
println "raSortCode: " + items[3]
println "raAccNum: " + items[4]
println "raReference: " + items[5]
println "raSendDate: " + items[6]
println "raRecDate: " + items[7]
println "raAmount: " + items[8]
println "raDummy1: " + items[9]
println "raFirstAmt: " + items[10]
println "raFirstDate: " + items[11]
println "raRegularAmt: " + items[12]
println "raRegularDate: " + items[13]
println "raFrequency: " + items[14]
println "raFee: " + items[15]
def toAdd = '"<salutation>$item[0]</salutation>"'
fragToAdd = new XmlSlurper().parseText(toAdd)
prnReq.ltrPrnReqs.ltrPrnReq.ltrData.appendNode(fragToAdd)
}
String outputFileName = "C:/Temp/letter_.xml"
XmlUtil xmlUtil = new XmlUtil()
xmlUtil.serialize(prnReq, new FileWriter(new File(outputFileName)))
}
You should be able to add the new node using appendNode.
Here is complete sample showing how to do it.
def xmlString = """<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>"""
def xml = new XmlSlurper().parseText(xmlString)
def ltrData = xml.'**'.find{it.name() == 'ltrData'}
ltrData.replaceBody()
ltrData.appendNode {
Salutation('text')
}
println groovy.xml.XmlUtil.serialize(xml)
You can quickly try it online demo

how to fix expecting anything but ''\n''; got it anyway

I have the following line in my code
def genList = (args[]?.size() >=4)?args[3]: "
when I run my whole code I get the following error
expecting anything but ''\n''; got it anyway at line: 9, column: 113
here I am adding the whole code so you can see what I am doing
def copyAndReplaceText(source, dest, targetText, replaceText){
dest.write(source.text.replaceAll(targetText, replaceText))
}
def dire = new File(args[0])
def genList = (args[]?.size() >=4)?args[3]: " // check here if argument 4 is provided, and generate output if so
def outputList = ""
dire.eachFile {
if (it.isFile()) {
println it.canonicalPath
// TODO 1: copy source file to *.bak file
copy = { File src,File dest->
def input = src.newDataInputStream()
def output = dest.newDataOutputStream()
output << input
input.close()
output.close()
}
//File srcFile = new File(args[0])
//File destFile = new File(args[1])
//File srcFile = new File('/geretd/resume.txt')
//File destFile = new File('/geretd/resumebak.txt')
File srcFile = it
File destFile = newFile(srcFile + '~')
copy(srcFile,destFile)
// search and replace to temporary file named xxxx~, old text with new text. TODO 2: modify copyAndReplaceText to take 4 parameters.
if( copyAndReplaceText(it, it+"~", args[1], args[2]) ) {
// TODO 3: remove old file (it)
it.delete()
// TODO 4: rename temporary file (it+"~") to (it)
// If file was modified and parameter 4 was provided, add modified file name (it) to list
if (genList != null) {
// add modified name to list
outputList += it + "\n\r"
}
}
}
}
// TODO 5: if outputList is not empty (""), generate to required file (args[3])
if (outputList != ""){
def outPut = new File(genList)
outPut.write(outputList)
}
Thank you
Just close your double quotes
def genList = (args?.size() >=4)?args[3]: ""
The specific OP question was already answered, but for those who came across similar error messages in Groovy, like:
expecting anything but '\n'; got it anyway
expecting '"', found '\n'
It could be caused due to multi-line GString ${content} in the script, which should be quoted with triple quotes (single or double):
''' ${content} ''' or """ ${content} """
Why do you have a single " at the end of this line: def genList = (args[]?.size() >=4)?args[3]: "?
You need to make it: def genList = (args[]?.size() >=4)?args[3]: ""
You need to add a ; token at the end of def outputList = ""
Also get rid of the " at the end of def genList = (args[]?.size() >=4)?args[3]: "

how to replace a string/word in a text file in groovy

Hello I am using groovy 2.1.5 and I have to write a code which show the contens/files of a directory with a given path then it makes a backup of the file and replace a word/string from the file.
here is the code I have used to try to replace a word in the file selected
String contents = new File( '/geretd/resume.txt' ).getText( 'UTF-8' )
contents = contents.replaceAll( 'visa', 'viva' )
also here is my complete code if anyone would like to modify it in a more efficient way, I will appreciate it since I am learning.
def dir = new File('/geretd')
dir.eachFile {
if (it.isFile()) {
println it.canonicalPath
}
}
copy = { File src,File dest->
def input = src.newDataInputStream()
def output = dest.newDataOutputStream()
output << input
input.close()
output.close()
}
//File srcFile = new File(args[0])
//File destFile = new File(args[1])
File srcFile = new File('/geretd/resume.txt')
File destFile = new File('/geretd/resumebak.txt')
copy(srcFile,destFile)
x = " "
println x
def dire = new File('/geretd')
dir.eachFile {
if (it.isFile()) {
println it.canonicalPath
}
}
String contents = new File( '/geretd/resume.txt' ).getText( 'UTF-8' )
contents = contents.replaceAll( 'visa', 'viva' )
As with nearly everything Groovy, AntBuilder is the easiest route:
ant.replace(file: "myFile", token: "NEEDLE", value: "replacement")
As an alternative to loading the whole file into memory, you could do each line in turn
new File( 'destination.txt' ).withWriter { w ->
new File( 'source.txt' ).eachLine { line ->
w << line.replaceAll( 'World', 'World!!!' ) + System.getProperty("line.separator")
}
}
Of course this (and dmahapatro's answer) rely on the words you are replacing not spanning across lines
I use this code to replace port 8080 to ${port.http} directly in certain file:
def file = new File('deploy/tomcat/conf/server.xml')
def newConfig = file.text.replace('8080', '${port.http}')
file.text = newConfig
The first string reads a line of the file into variable. The second string performs a replace. The third string writes a variable into file.
Answers that use "File" objects are good and quick, but usually cause following error that of course can be avoided but at the cost of loosen security:
Scripts not permitted to use new java.io.File java.lang.String.
Administrators can decide whether to approve or reject this signature.
This solution avoids all problems presented above:
String filenew = readFile('dir/myfile.yml').replaceAll('xxx','YYY')
writeFile file:'dir/myfile2.yml', text: filenew
Refer this answer where patterns are replaced. The same principle can be used to replace strings.
Sample
def copyAndReplaceText(source, dest, Closure replaceText){
dest.write(replaceText(source.text))
}
def source = new File('source.txt') //Hello World
def dest = new File('dest.txt') //blank
copyAndReplaceText(source, dest) {
it.replaceAll('World', 'World!!!!!')
}
assert 'Hello World' == source.text
assert 'Hello World!!!!!' == dest.text
other simple solution would be following closure:
def replace = { File source, String toSearch, String replacement ->
source.write(source.text.replaceAll(toSearch, replacement))
}

Resources