How to get files by using index of List files in groovy - groovy

I got the List of all files by using but it give all files , I need specific files from list.
import groovy.io.FileType
def list = []
def dir = new File("path_to_parent_dir")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file
}
list.each {
println it.path
}

The method File.eachFileRecurse(FileType, Closure) can only filter by FileType; the options being FILES, DIRECTORIES, and ANY (everything). Keep in mind this is file type in the filesystem sense, and has nothing to do with the file contents. For instance, an HTML document and a PNG image are both FILES.
If you want to filter by, say, the file extension, you can use File.traverse(Map, Closure):
import groovy.io.FileType
def list = []
def dir = new File("source")
dir.traverse(type: FileType.FILES, nameFilter: ~/.*\.html/) { list << it }
list.each {
println it.path
}
In the example above, I used the nameFilter option to specify a regular expression to filter the file name by. You can about the other available options in the documentation.

Related

How to read a file in Groovy into a string, without knowing the path to the file?

In extension to this question.
Is it possible to read a file into a string without knowing the path to the file? - I only have the file as a 'def'/type-less parameter, which is why I can't just do a .getAbsolutePath()
To elaborate on this, this is how I import the file (which is from a temporary .jar file)
def getExportInfo(path) {
def zipFile = new java.util.zip.ZipFile(new File(path))
zipFile.entries().each { entry ->
def name = entry.name
if (!entry.directory && name == "ExportInfo") {
return entry
}
}
}
A ZipEntry is not a file, but a ZipEntry.
Those have almost nothing in common.
With def is = zipFile.getInputStream(entry) you get the input stream to the zip entry contents.
Then you can use is.text to get the contents as String in the default platform encoding or is.getText('<theFilesEncoding>') to get the contents as String in the specified encoding, exactly the same as you can do on a File object.

How read all files in the folder and replace the pattern in file using Groovy

import groovy.io.FileType
import java.io.File;
def list = []
def dir = new File("C:\\Users\\Desktop\\CodeTest")
dir.eachFileRecurse (FileType.FILES)
{
file ->list << file
}
list.each
{
println it.path
}
//Replace the pattern in file and write to file sequentially.
def replacePatternInFile(file, Closure replaceText)
{
file.write(replaceText(file.text))
}
def file = new File(file)
def patternToFind1 = ~/</
def patternToFind2 = ~/>/
def patternToReplace1 = '&lt'
def patternToReplace2 = '&gt'
//Call the method
replacePatternInFile(file){
it.replaceAll(patternToFind1,patternToReplace1)
}
replacePatternInFile(file){
it.replaceAll(patternToFind2,patternToReplace2)
}
println file.getText()
I am able to change the pattern for one file but I want to read all the files in the folder and replace the pattern in each file one by one
while executing it:
ERROR:An error occurred [Could not find matching constructor for: java.io.File(java.util.ArrayList)], see error log for details
You have many problems with your code...
1) You don't need to import:
import java.io.File;
2) When you call:
def file = new File(file)
There is no variable called file in new File(file) (did you mean files?)
3) If you did mean new File(files) then that is where your error is... You can't make a new file from a list of Strings
4) The entity for > is > NOT &gt... The same for < (it needs a semicolon at the end)
You will need to iterate your list of Strings (files.each { path -> ?) and then work on each one in turn.
Though 2) and 3) make me suspect that the above code isn't your real code, but a pretend copy from memory (or a badly redacted copy), as the above code will not give you the error you say you're getting

groovy read from URL file and store it in the list

I have file stored in the website, I want to read the file and store each line in array list.
Currently using this code, it works. Is there a better way of doing this part of the code.
def data = u.toURL().text
def keys = new ArrayList()
data.eachLine {
keys.add(it)
}
Why not:
def keys = u.toURL().readLines()
?
As in the docs.
you could simplify it a bit:
def keys = []
u.toURL().text.eachLine{ keys << it }
and for such simple kind of job, it's just fine

Get folder name from list of string

I have a list of a hundred folders like below:
C:\Mother\Son\foler_A\a_file.txt
C:\Mother\Son\foler_A\foler_B\a_file.txt
C:\Mother\Son\foler_B\a_file.txt
C:\Mother\Son\foler_C\foler_D\a_file.txt
...
Can someone help me to get the list of the lastest folder level like:
['folder_A', [folder_B], [folder_B],[folder_D]]
If these files actually exist on your system, you could do:
def parents = folders.collect { new File(it).parentFile?.name }
If not, you could do:
def parents = folders*.split( '\\\\' )*.getAt(-2)

Groovy load .csv files

How to read and import .csv file in groovy on grails. I have .csv file with data and
need to import in to db using user interface .
There are as always different possibilities to work with CSV files in Groovy.
As Groovy is fully interoperable with Java, you can use one of the existing CSV libararies, e.g. OpenCSV.
Depending on the complexity of the CSV file you are using, you can also use the standard file/string handling possibilities of Groovy:
def sql = Sql.newInstance("jdbc:mysql://localhost:3306/mydb",
"user", "pswd", "com.mysql.jdbc.Driver")
def people = sql.dataSet("PERSON")
new File("users.csv").splitEachLine(",") {fields ->
people.add(
first_name: fields[0],
last_name: fields[1],
email: fields[2]
)
}
EDIT:
Kelly Robinson just wrote a nice blog post about the different possibilities that are available to work with CSV files in Groovy.
EDIT #2:
As Leonard Axelsson recently released version 1.0 of his GroovyCVS library, I thought I should definitely add this to the list of options.
Using xlson's GroovyCSV:
#Grab('com.xlson.groovycsv:groovycsv:1.3')
import static com.xlson.groovycsv.CsvParser.parseCsv
for(line in parseCsv(new FileReader('countries.csv'), separator: ';')) {
println "Country=$line.COUNTRY, Capital=$line.CAPITAL"
}
The field names are taken from the header of the CSV file.
If the CSV file has no header, you can specify the field names programmatically.
With Apache Commons-CSV
#Grab('org.apache.commons:commons-csv:1.2')
import org.apache.commons.csv.CSVParser
import static org.apache.commons.csv.CSVFormat.*
import java.nio.file.Paths
Paths.get('countryInfo.txt').withReader { reader ->
CSVParser csv = new CSVParser(reader, DEFAULT.withHeader())
for (record in csv.iterator()) {
println record.dump()
}
}
Commons-CSV has nice API and I recommend that.
With GroovyCSV:
#Grab('com.xlson.groovycsv:groovycsv:0.2')
import com.xlson.groovycsv.CsvParser
def csv = '''Name,Lastname
Mark,Andersson
Pete,Hansen'''
def data = new CsvParser().parse(csv)
for(line in data) {
println "$line.Name $line.Lastname"
}
(Taken from it's samples)
Last resort: Regular expression.
Here's how I parsed a file that might contain a quoted escaped string in it's fourth column:
File detailedStatsFile = new File("stats.csv");
detailedStatsFile.eachLine { line, number ->
// Number Of Executions, Total Milliseconds, Milliseconds per execution, "Type"
def match = line =~ /([^,]*?),\s*([^,]*?),\s*([^,]*?),\s*(?:([^",]+)|(?:"((?:[^\\"]++(?:\\")?)++)"))$/; //"
if (!match.matches())
continue;
def numberOfExecs = Integer.valueOf(match.group(1));
def totalMillis = Integer.valueOf(match.group(2));
def detailedStatName = match.group(4);
if (detailedStatName == null)
detailedStatName = match.group(5).replaceAll('\\"','"');
Example using opencsv
#Grab('com.opencsv:opencsv:4.0')
import com.opencsv.CSVReader
import com.opencsv.CSVWriter
class TestCsvReader {
static main(args) {
def csv = '''"a","b","c"
"d","e","f"
'''
def Reader csvFileReader = new StringReader(csv)
def Writer csvFileWriter = new PrintWriter(System.out)
def CSVReader reader = new CSVReader(csvFileReader)
def CSVWriter writer = new CSVWriter(csvFileWriter)
reader.iterator().each { fields ->
writer.writeNext(fields)
}
reader.close()
writer.close()
}
}
Example from production code done by SAP developers in SCPi SAP Cloud Platform Integration groovy iFlow:
String[] parseCSVLine(String line) {
// Create a pattern to match breaks
Pattern p =
Pattern.compile(",(?=([^\"]*\"[^\"]*\")*(?![^\"]*\"))");
// Split input with the pattern
String[] fields = p.split(line);
for (int i = 0; i < fields.length; i++) {
// Get rid of residual double quotes
fields[i] = fields[i].replace("\"", "");
}
return fields;
}
Usage:
cols = parseCSVLine(line)
value = cols[0]
value = cols[1]
I prefer a slight tweak on the accepted answer: zip the columns and values together, as opposed to indexing each one by number. The result is slightly shorter code.
def sql = Sql.newInstance("jdbc:mysql://localhost:3306/mydb", "user", "pswd", "com.mysql.jdbc.Driver")
def people = sql.dataSet("PERSON")
def columns = ['first_name', 'last_name', 'email']
new File("users.csv").splitEachLine(",") {values ->
people.add([columns, values].transpose().collectEntries())
}

Resources