How to use not equalto in Groovy in this case - groovy

I just want to print files which are not located in ss
def folder = "./test-data"
// println "reading files from directory '$folder'"
def basedir = new File(folder)
basedir.traverse {
if (it.isFile()) {
def rec = it
// println it
def ss = rec.toString().substring(12)
if(!allRecords contains(ss)) {
println ss
}
}

Your question isn't exactly clear, but it looks like you're just trying to do
if (!allRecords.contains(ss)) {
println ss
}
in the last part of your code segment.

Related

Regex for groovy not working

Please find below my code. I am trying to iterate through files and in a directory and print out all the match to the regex: (&)(.+?\b)
however this doesn't seem to work (it returns an empty string). Where did I go wrong?
import groovy.io.FileType
class FileExample {
static void main(String[] args) {
def list = []
def dir = new File("*path to dir*")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file.name;
def s= "${file.text}";
def w = s.toString();
w.readLines().grep(~/(&)(.+?\b)/)
}
}
}
I figured it out:
import groovy.io.FileType
class FileExample {
static void main(String[] args) {
def list = []
def dir = new File("/path/to/directory/containingfiles")
def p = []
dir.eachFileRecurse (FileType.FILES) {
file -> list << file.name
def s = file.text
def findtp = (s =~ /(&)(.+?\b)/)
findtp.each {
p.push(it[2])
// As I'm only interested in the second matched group
}
}
p.each {
println it
}
}
}
Now, all the matched strings are stored in the array p and can be printed/used elsewhere by p[0] etc.
w.readLines().grep(~/(&)(.+?\b)/) does not do any output, it gives you the matching lines as return value, so if you change it to println w.readLines().grep(~/(&)(.+?\b)/) or w.readLines().grep(~/(&)(.+?\b)/).each { println it }, you will get the matched lines printed on stdout.
Btw.
def s= "${file.text}";
def w = s.toString();
w.readLines()
is just a biiiig waste of time. It is exactly the same as file.text.readLines().
"${file.text}" is a GString that replaces the placeholders on evaluation, but as you have nothing but the file.text placeholder, this is the same as file.text as String or file.text.toString().
But as file.text actually is a String already, it is identical to file.text.
And even if you would need the GString because you have more than the placeholder in it, GString already has a readLines() method, so no need for using .toString() first, even if a GString would be necessary.

Groovy grep words in file

I want to grep words in file from path. How do it in groovy way ? How count how many words I find each file ?
import groovy.io.FileType
def splitStatements() {
String path = "C:\\Users\\John\\test"
def result = new AntBuilder().fileset( dir: path ) {
containsregexp expression:['END','BEGIN']
}*.file
println result
}
splitStatements()
That's doing that what I want :
def wordCount_END = 0
def wordCount_BEGIN = 0
def dir = new File("C:\\Users\\John\\test")
dir.eachFileRecurse (FileType.FILES) { file ->
Scanner s = new Scanner(file)
while (s.hasNext()) {
if (s.next().equals('BEGIN')) wordCount_END++
}
}
dir.eachFileRecurse (FileType.FILES) { file ->
Scanner s = new Scanner(file)
while (s.hasNext()) {
if (s.next().equals('END')) wordCount_BEGIN++
}
}
println("END count per lock: " + wordCount_END)
println("BEGIN count per lock: " + wordCount_BEGIN)
}

groovy print environments from groovy.config

how do I print available environments from a config file? What is the form of the ojbect ConfigSlurper creates?
I tried
def config2 = new ConfigSlurper().parse(new File('obieeadmincfg.groovy').toURL())
config2.config.environments.each { println ${it} }
and
println prettyPrint(toJson(config2))
and
for ( i in 0 ..config2.config.environments.size()-1)
println config2.config.environments[i]
groovy.config
//Config3.groovy
obieadmin {
//default values
serverurl = "http://default.mycompany.com"
}
environments {
pldev01 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
plsbx02 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
}
I'm afraid you can't do this out-of box.
But using a bit of Groovy Metaprogramming it's achievable.
Groovy config slurper parses proper Groovy file, and you can do the same with GroovyShell. You can catch call to environment method providing closure in binding. In that closure you have to collect all top-level method calls(with same methodMissing).
Providing base script with property and method missing handlers, you can suppress runtime errors, and execute script without much care to other properties.
Not the nicest path, but it works.
package test
import org.codehaus.groovy.control.CompilerConfiguration
class A extends Script {
def propertyMissing(String name) { null }
def propertyMissing(String name, def arg) {}
def methodMissing(String name, def args) {}
#Override Object run() { null }
}
class NameCollector {
def envs = []
def methodMissing(String name, def args) { envs << name }
}
// configure interceptors.
def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = 'test.A'
def nc = new NameCollector()
def environments = { Closure it ->
it.delegate = nc;
it.resolveStrategy = Closure.DELEGATE_ONLY
it()
}
// execute config script
new GroovyShell([environments: environments] as Binding, configuration).evaluate(new File("config.groovy"))
nc.envs // Return, print them.
Not sure if this is going to work forever but currently you can do it by overriding the setting for the 'environments' conditional block, like this:
def config = """environments {
dev {
foo = "bar"
}
prod {
foo = "baz"
}
}"""
def configSlurper = new ConfigSlurper()
configSlurper.registerConditionalBlock('environments', null)
assert configSlurper.parse(config).environments.keySet() == ['dev', 'prod'].toSet()

Groovy: XmlSlurper, Failed to replace the node first and try to append the same node again. any one faced this issue

//Unable to add replaced nodes back to xml using xml slurper. Throws stackoverflow exception. Now idea how to do it
def xml = """<container>
<listofthings>
<thing id="100" name="foo"/>
</listofthings>
</container>"""
def root = new XmlSlurper().parseText(xml)
def fun = new ArrayList(root.listofthings.collect{it})
root.listofthings.thing.each {
it.replaceNode {}
}
root.listofthings.appendNode ( { thing(id:102, name:'baz') })
fun.each {
root.listofthings.appendNode it
}
def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
String result = outputBuilder.bind { mkp.yield root }
print result
You call:
def fun = new ArrayList(root.listofthings.collect{it})
Which sets fun to be the node <listofthings> (and btw could be shortened to: def fun = root.listofthings)
Then on the line:
fun.each {
root.listofthings.appendNode it
}
You append this node to the node <listofthings>. This means your tree will be never ending (as you are attaching a node to itself), and hence the StackOverflowException
To get the code to run, you can change it to:
import groovy.xml.StreamingMarkupBuilder
def xml = """<container>
| <listofthings>
| <thing id="100" name="foo"/>
| </listofthings>
|</container>""".stripMargin()
def root = new XmlSlurper().parseText(xml)
root.listofthings.thing*.replaceNode {}
root.listofthings.appendNode {
thing( id:102, name:'baz' )
}
def outputBuilder = new StreamingMarkupBuilder()
String result = outputBuilder.bind { mkp.yield root }
print result
ie: get rid of the recursive node addition.
However, I'm not sure what you were trying to do with the recursive addition, so this probably doesn't do what you wanted to do... Can you explain more what result you wanted to see?
Edit
I managed to get XmlParser to do what I think you were trying to do?
def xml = """<container>
| <listofthings>
| <thing id="100" name="foo"/>
| </listofthings>
|</container>""".stripMargin()
def root = new XmlParser().parseText(xml)
def listofthings = root.find { it.name() == 'listofthings' }
def nodes = listofthings.findAll { it.name() == 'thing' }
listofthings.remove nodes
listofthings.appendNode( 'thing', [ id:102, name:'baz' ] )
nodes.each {
listofthings.appendNode( it.name(), it.attributes(), it.value() )
}
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
def result = writer.toString()
print result
That prints:
<container>
<listofthings>
<thing id="102" name="baz"/>
<thing id="100" name="foo"/>
</listofthings>
</container>

Tail a file in Groovy

I am wondering is there is a simple way to tail a file in Groovy? I know how to read a file, but how do I read a file and then wait for more lines to be added, read them, wait, etc...
I have what I am sure is a really stupid solution:
def lNum = 0
def num= 0
def numLines = 0
def myFile = new File("foo.txt")
def origNumLines = myFile.eachLine { num++ }
def precIndex = origNumLines
while (true) {
num = 0
lNum = 0
numLines = myFile.eachLine { num++ }
if (numLines > origNumLines) {
myFile.eachLine({ line ->
if (lNum > precIndex) {
println line
}
lNum++
})
}
precIndex = numLines
Thread.sleep(5000)
}
Note that I am not really interested in invoking the Unix "tail" command. Unless it is the only solution.
I wrote a groovy class which resembles the basic tail functionality:
class TailReader {
boolean stop = false
public void stop () {
stop = true
}
public void tail (File file, Closure c) {
def runnable = {
def reader
try {
reader = file.newReader()
reader.skip(file.length())
def line
while (!stop) {
line = reader.readLine()
if (line) {
c.call(line)
}
else {
Thread.currentThread().sleep(1000)
}
}
}
finally {
reader?.close()
}
} as Runnable
def t = new Thread(runnable)
t.start()
}
}
The tail method taks a file and closure as parameters. It will run in a separate thread and will pass each new line that will be appended to the file to the given closure. The tail method will run until the stop method is called on the TailReader instance. Here's a short example of how to use the TailReader class:
def reader = new TailReader()
reader.tail(new File("/tmp/foo.log")) { println it }
// Do something else, e.g.
// Thread.currentThread().sleep(30 * 1000)
reader.stop()
In reply to Christoph :
For my use case, I've replaced the block
line = reader.readLine()
if (line) {
c.call(line)
}
else {
Thread.currentThread().sleep(1000)
}
with
while ((line = reader.readLine()) != null)
c.call(line)
Thread.currentThread().sleep(1000)`
... != null => to ensure empty lines are outputted as well
while (... => to ensure every line is read as fast as possible

Resources