I have to zip multiple files together using 7zip.exe. I have paths of two files say file1 and file2. I append the two paths using the following.
string filetozip = file1+ "\"" + file2+" "; and do the below
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Freedom\7-Zip\7z.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.Arguments = string.Format(" a -tzip \"{0}\" \"{1}\" -mx=9 -mem=AES256 -p\"{2}\" ", destZipFile, filetozip , zipPassword);
proc.Start();
proc.WaitForExit();
if (proc.ExitCode != 0)
{
throw new Exception("Error Zipping Data File : " + proc.StandardError.ReadToEnd());
}
filetozip is passed as an argument above. The above code does not work properly. I am getting proc.ExitCode=1. Which is the right way to append the file paths.Is string filetozip = file1+ "\"" + file2+" "; the right way? I can have one or more files. What is the separator used?
The command line that you want to create looks like
plus the required switches (arguments quoted and space delimited).
String.Join or StringBuilder are some coding things that may be helpful
Related
I have series of xml files placed in 2 separate folders as below. My objective is to read each file one at a time from both folders and apply xmlunit comaprison methods.
Folder1 : actual1.xml
actual2.xml
actual3.xml
Folder2 : compare1.xml
compare2.xml
compare3.xml
Part1: Am reading each file at a time from both folders by using below script. I welcome suggestions if there are more simpler methods to do this
log.info "**********Read files from Folder1************"
def xml_file1 = []
new File("D:\\GroovyTest\\Folder1").eachFile{ f ->
f (f.isFile()&& f.name.contains('.xml'))
{
def filename = f.name[0..-1]
xml_file1.add(filename)
log.info filename
}
}
if (xml_file1.size() <1)
{
testRunner.fail("No request files found")
}
log.info "**********Read files from Folder2************"
def xml_file2 = []
new File("D:\\GroovyTest\\Folder2").eachFile{ f ->
if (f.isFile()&& f.name.contains('.xml'))
{
def filename = f.name[0..-1]
xml_file2.add(filename)
log.info filename
}
}
if (xml_file2.size() <1)
{
testRunner.fail("No request files found")
}
Part2: Script to perform comparison for each combination of xml files contained in array xml_file1 and xml_file2.
Am actually stuck at this part as the below script works for single files if each xml file is kept in a string, but i have to pass an array as arguments since i have series of xml files to be compared. I get a run time error - groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.FileInputStream(java.util.ArrayList) error at line: 60
InputStream xml_stream1 = new FileInputStream(xml_file1)
String xml1 = getStringFromInputStream(xml_stream1)
InputStream xml_stream2 = new FileInputStream(xml_file2)
String xml2 = getStringFromInputStream(xml_stream2)
def factory = TransformerFactory.newInstance()
def transformer = factory.newTransformer(new StreamSource(new StringReader(xslt)))
StreamResult result_xml1 = new StreamResult(new StringWriter());
transformer.transform(new StreamSource(new StringReader(xml1)), result_xml1)
xml1 = result_xml1.getWriter().toString()
StreamResult result_xml2 = new StreamResult(newStringWriter());
transformer.transform(new StreamSource(new StringReader(xml2)), result_xml2)
xml2 = result_xml2.getWriter().toString()
XMLUnit.setIgnoreComments(true)
DifferenceListener differenceListener = newIgnoreTextAndAttributeValuesDifferenceListener();
DetailedDiff myDiff = new DetailedDiff(new Diff(xml1, xml2));
myDiff.overrideDifferenceListener(differenceListener);
myDiff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
log.info "similar ? " + myDiff.similar()
log.info "identical ? " + myDiff.identical()
List allDifferences = myDiff.getAllDifferences();
for (Object object : allDifferences) {
Difference difference = (Difference)object;
log.info(difference);
}
Could someone also help me with methods to ignore empty tags during comparison?
Thanks
I am running the following Groovy method to create a text file.
def createFile(String path, String fileName)
{
new File("$path/$fileName").delete()
def txtFileInfo = []
String a = "2014111620141117COMPANYX"
String b = "2104808660"
String c = "2104808662"
String d = "00000002"
txtFileInfo << a.trim()
txtFileInfo << b.trim()
txtFileInfo << c.trim()
txtFileInfo << d.trim()
File file = new File("$path/$fileName")
txtFileInfo.each {
file << ("${it.replaceAll("[\n\r]", "")}\n")
}
}
The issue is it always adds a blank line at the end of the file. (I.e., after 00000002 in the above example there is a blank line below that in the created file.)
How can I get rid of that blank line? What I am doing wrong here?
Thanks
You are appending a newline character to the end. You have that hardcoded in your example.
You could replace this:
File file = new File("$path/$fileName")
txtFileInfo.each {
file << ("${it.replaceAll("[\n\r]", "")}\n")
}
With something like this...
File file = new File("$path/$fileName")
file << txtFileInfo.join('\n')
I hope that helps.
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]: "
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 am trying to write output to a text file stored in my azure container.
Following is my woker role snippet for it :
string copyTemp="";
copyTemp += "hi" + "\n";
copyTemp += "hello" + "\n";
if (String.IsNullOrEmpty(copyTemp))
return;
using (var memoryStream = new MemoryStream())
{
memoryStream.Write(System.Text.Encoding.UTF8.GetBytes(copyTemp), 0, System.Text.Encoding.UTF8.GetBytes(copyTemp).Length);
memoryStream.Position = 0;
blockBlob.UploadFromStream(memoryStream);
}
Now, when i download and check my blob,the output doesn't feature a new line.
"hihello"
Does anyone have an idea,what's goin wrong ?
Have you tried using Environment.NewLine rather than adding "\n" to your strings?
It might just be that your "\n" is not a full new line in the place you are reading it. In windows I believe you need a "\r\n" to get a proper new line character.
You can read about the differences between new line (\n) and carriage return (\r) and which systems use which on Wikipedia but that clarifies h that windows uses a carriage return and a line feed to signify a new line.
So if you had downloaded your blob on a Mac or on Linux it probably would have displayed as you expected.
The best solution for C# is to use the static string property Environment.NewLine. You can use it for writing text content to files, to azure blobs, to console output, and you will never have to think whether it is \n or \r\n. In your case the code will be:
string copyTemp="";
copyTemp += "hi" + Environment.NewLine;
copyTemp += "hello" + Environment.NewLine;