I have a sample file like the following:
CREATE GLOBAL TEMPORARY TABLE tt_temp_user_11
(
asdfa
)
CREATE GLOBAL TEMPORARY TABLE tt_temp_user_11
(
asdfas
)
some other text in file
I want to convert this file into following:
CREATE GLOBAL TEMPORARY TABLE 1
(
asdfa
)
CREATE GLOBAL TEMPORARY TABLE 2
(
asdfas
)
some other text in file
So basically every TEMPORARY TABLE occurrence will have number appended to it.
So far I have the following groovy script:
int i = 0
new File ("C:\\Not_Modified").eachFile{file ->
println "File name: ${file.name}"
new File ("C:\\Not_Modified\\"+file.name).eachLine {line ->
if (line.indexOf("TEMPORARY TABLE")>0)
{
i++
}
}
println "There are ${i} occurences of TEMPORARY TABLE"
}
How can I change the text in the file? should I be writing to a different file?
btw, I have directory in my script because I will be working on lot of these type of files in a directory.
I should have opted perl for this task but wanted to give groovy a try.
I wrote a little function that works kind of like File.eachLine{} works but allows editing.
You can use it like this:
def n=1
modifyFile("filename"){
if(it.startsWith("CREATE GLOBAL TEMPORARY TABLE"))
return "CREATE GLOBAL TEMPORARY TABLE " + n++
return it // Re-inserts unmodified line"
}
This is pretty easy to code--whatever is returned from the closure is written out to the new file. If you want a different file, provide two filenames.
/**
* This will completely re-write a file, be careful.
*
* Simple Usage:
*
* modifyFile("C:\whatever\whatever.txt") {
* if(it.contains("soil"))
* return null // remove dirty word
* else
* return it
* }
*
* The closure must return the line passed in to keep it in the file or alter it, any alteration
* will be written in it's place.
*
* To delete an entire line instead of changing it, return null
* To add more lines after a given line return: it + "\n" + moreLines
*
* Notice that you add "\n" before your additional lines and not after the last
* one because this method will normally add one for you.
*/
def modifyFile(srcFile, Closure c) {
modifyFile(srcFile, srcFile, c)
}
def modifyFile(srcFile, destFile, Closure c={println it;return it}) {
StringBuffer ret=new StringBuffer();
File src=new File(srcFile)
File dest=new File(destFile)
src.withReader{reader->
reader.eachLine{
def line=c(it)
if(line != null) {
ret.append(line)
ret.append("\n")
}
}
}
dest.delete()
dest.write(ret.toString())
}
}
I'm think you should write to different file, it's a good practice.
Put something like line below inside your if {} (instead of i++)
line = line.replaceFirst(/^(create temporary table) (.*)/, "\$1 table${++i}")
and then, outside of your if write line variable into outfile
BTW i'm think you better use ==~ in your if instead of indexOf
Related
I have a csv file (UTF-8 with BOM) like this
NAME,F1,F2,
test1,field1,field2
test2,field1,field2
test3,field1,field2
test4,field1,field2
test5,field1,field2
test6,field1,field2
I would like to discard the first three lines and create new csv (UTF-8 with BOM)
NAME,F1,F2,
test4,field1,field2
test5,field1,field2
test6,field1,field2
I get some idea from the page and code this in JSR223 PreProcessor
def originalCsvFile = new File('g:/Workspace/1.csv')
def newCsvFile = new File('g:/Workspace/2.csv')
originalCsvFile.readLines().take(5).each {line ->
newCsvFile.withWriter('UTF-8') { writer ->
writer.writeLine line
}
}
The above code does not work.
It is better to put the new csv path to the variable, I want to get the variable in jmeter CSV Data Set Config
Do you realize that:
take(5) function returns 5 first lines of the list
newCsvFile.withWriter function overwrites the file with the new data each time it's being called
So I believe you're looking for copying and pasting something like this:
originalCsvFile.readLines().eachWithIndex { line, index ->
if (index == 0 || index > 3) {
newCsvFile.withWriterAppend('UTF-8') { writer ->
writer.writeLine line
}
}
}
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It
Not as elegant, perhaps, but this is how I would do it:
List li = originalCsvFile.readLines()
newCsvFile.append(li[0] + "\n", 'UTF-8') //headers
li[4..-1].each { newCsvFile.append(it + "\n", 'UTF-8') }
I'm trying to create a Substfile rule that will expand a key to the transformed contents of another file. I'm not clear on the setup here to ensure the source file is registered as a dependency.
Logically I want something like:
out = env.Substfile( 'file.in', SUBST_DICT = {
'%SOME_CONTENT%': transform( readfile('depends.txt') ),
}
I'm using a combination of Action and Command to do what I want. I ended up not using Substfile, though it could probably be chained to the command.
This RawStringIt action loads a text file and emits a C++ encoded raw string for the content.
def RawStringIt(varName):
def Impl(target, source, env):
content = source[0].get_text_contents()
with open(target[0].get_path(), 'w') as target_file:
target_file.write( "std::string {} = R\"~~~~({})~~~~\";".format(varName,content))
return 0
return Action(Impl, "creating C++ Raw String $TARGET from $SOURCE" )
base_leaf = env.Command( 'include/runner/base.leaf.hpp', '../share/base.leaf', RawStringIt("dataBaseLeaf") )
-Is there any way to pass Global Properties from external file or something?
-I don't want to navigate Preference-Global Properties and changing the values.
-Is there any alternative way to do this.
Thanks,
Arivazhagan
You can parse external file in groovy script Step, for example *.csv file with values into the local groovy variables, and then set value in Properties of Test Suite or Test Case or Global Properties too.
Example of parsing *.csv file:
def testDataSet = []
def index = testRunner.testCase.getPropertyValue("index")
int indx = index.toInteger()
def fileName = "phoneNumbers.csv"
//read from file
new File(fileName).eachLine { line -> testDataSet.add( line.split(";") ) }
log.info( "Read " + testDataSet.size() + " test values from " + fileName )
//convert value to properties
def testDataLine = testDataSet[indx]
phoneNumber = testDataLine[0].value as String
log.info phoneNumber
Example of set property:
testRunner.testCase.setPropertyValue("phoneNumber", phoneNumber)
indx++
String indexString = Integer.toString(indx)
testRunner.testCase.setPropertyValue("index", indexString)
Example of set Global Preporty:
globalProperty = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "MyProp" )
more info provide here https://www.soapui.org/scripting-properties/tips-tricks.html
Global properties are stored in soapui-settings.xml in the user.dir. If you change it, it will be recognized by readyApi/soapUI.
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))
}
I've been tasked with creating a new server modification for Crysis Wars. I have ran into a particular issue that it cannot read the old ban-file (this is required in order to keep the server consistent). The Lua code itself does not seem to have any errors, but it's just not getting any of the data.
Looking at the code I'm using for this below, can you find anything wrong with it?
This is the code I'm using for this:
function rX.CheckBanlist(player)
local Root = System.GetCVar("sys_root");
local File = ""..Root.."System/Bansystem/Raptor.xml";
local FileHnd = io.open(File, "r");
for line in FileHnd:lines() do
if (not string.find(line, "User:Read")) then
System.Log("[rX] File Read Error: System/Raptor/Banfile.xml, The contents are unexpected.");
return false;
end
local Msg, Date, Reason, Type, Domain = string.match(line, "User:Read( '(.*)', { Date='(.*)'; Reason='(.*)'; Typ='(.*)'; Info='(.*)'; } );");
local rldomain = g_gameRules.game:GetDomain(player.id);
if (Domain == rldomain) then
return true;
else
return false;
end
end
end
Also, the actual file reads as this, but I can't get the " to work in Lua properly. Could this be the issue?
User:Read( "Banned", { Date="31.03.2011"; Reason="WEBSTREAM"; Typ="Inetnum"; Info="COMPUTER.SED.gg"; } );
You may prefer using Lua's [[ for multiline string when you want to include quotes inside quotes etc.
Also, you'd have to escape the ( and ) while matching:
local Msg, Date, Reason, Type, Domain = line:match([[User:Read%( "(.-)", { Date="(.+)"; Reason="(.+)"; Typ="(.+)"; Info="(.+)"; } %);]])
And the results will be as expected: http://codepad.org/gN8kSL6H