Parsing file, ignoring comments and blank lines - go

As the title says, I am trying to parse a file but ignore comments (started with #) or blank lines. I have tried to make a system for this, yet it always seems to ignore that it should be ignoring comments and/or blank lines.
lines := strings.Split(d, "\n")
var output map[string]bool = make(map[string]bool)
for _, line := range lines {
if strings.HasPrefix(line, "#") != true {
output[line] = true
} else if len(line) > 0 {
output[line] = true
}
}
When run (this is part of a function), it outputs the following
This is the input ('d' variable):
Minecraft
Zerg Rush
Pokemon
# Hello
This is the output when printed ('output' variable):
map[Minecraft:true Zerg Rush:true Pokemon:true :true # Hello:true]
My issue here is that it still keeps the "" and "# Hello" values, meaning that something failed, something I haven't been able to figure out.
So, what am I doing wrong that this keeps the improper values?

len(line) > 0 will be true for the "# Hello" line, so it will get added to output.
Currently, you are adding lines that either don't start with a # or are not empty. You need to only add lines that satisfy both conditions:
if !strings.HasPrefix(line, "#") && len(line) > 0 {
output[line] = true
}

Related

"Unexpected_end, expecting keyword_end"

I have an issue in one of my functions in my code. I am new to Ruby, so I am unsure of where my syntax error is. My irb is giving me a syntax error related to my end keywords, but I believe the syntax is correct
def function1
print "function 1 \n"
print "Please type 4 lines \n"
i = 0
fptr = (File.new("myFile.txt", "w"))
while i < 4
line = gets
fptr.write(line "\n")
i++
end
fptr.close()
end
This function should print two output lines, open a txt file, take in 4 lines of user input, and write them to the said file.
The problem is that i++ is not valid Ruby. Use i += 1 instead.

Hidden flag default values

Go provides easy CLI switches aka flags.
var debug = flag.Bool("debug", false, "enable debugging")
var hostname = flag.String("hostname", "127.0.0.1", "hostname")
flag.Parse()
As expected this yields
> ./program -h
Usage:
-debug
enable debugging
-hostname string
hostname (default "127.0.0.1")
I would like to hide the (default "127.0.0.1") part of specific flags.
Searching on SO and around suggested use of flag.FlagSet.
var shown flag.FlagSet
var hidden flag.FlagSet
var debug = shown.Bool("debug", false, "enable debugging")
var hostname = hidden.String("hostname", "127.0.0.1", "hostname")
flag.Usage = func() {
shown.PrintDefaults()
}
flag.Parse()
//shown.Parse(os.Args[0:]) // tried to solve "flag provided but not defined"
Output part shows only "debug" flag, however this breaks actual flag usage.
> ./program -debug
flag provided but not defined: -debug
Usage of ./program:
-debug
enable debugging
And this is not ideal either, since I would like to see the available flag, just hide the default value.
Desired output:
> ./program -h
Usage:
-debug
enable debugging
-hostname string
hostname
Best solution so far is the one Eugene proposed. Thanks!
var debug = flag.Bool("debug", false, "enable debugging")
var hostname = flag.String("hostname", "", "hostname")
flag.Parse()
defaultHostname := "127.0.0.1"
if *hostname == "" {
*hostname = defaultHostname
}
You can just copy & paste the codes from the source and remove the print default part.
flag.Usage = func() {
f := flag.CommandLine
_, _ = fmt.Fprintf(f.Output(), "Usage of %s:\n", os.Args[0])
flag.VisitAll(func(flag_ *flag.Flag) {
if flag_.Usage == "" {
return
}
s := fmt.Sprintf(" -%s", flag_.Name) // Two spaces before -; see next two comments.
name, usage := flag.UnquoteUsage(flag_)
if len(name) > 0 {
s += " " + name
}
// Boolean flags of one ASCII letter are so common we
// treat them specially, putting their usage on the same line.
if len(s) <= 4 { // space, space, '-', 'x'.
s += "\t"
} else {
// Four spaces before the tab triggers good alignment
// for both 4- and 8-space tab stops.
s += "\n \t"
}
s += strings.ReplaceAll(usage, "\n", "\n \t")
_, _ = fmt.Fprint(f.Output(), s, "\n")
})
}
flag.Parse()

golang flag hidden options from print defaults

this is my actual code :
package main
import (
"flag"
)
var loadList = ""
var threads = 50
var skip = 0
func main() {
//defaults variables
flag.StringVar(&loadList, "f", "", "load links list file (required)")
flag.IntVar(&threads,"t", 50, "run `N` attempts in parallel threads")
flag.IntVar(&skip, "l", 0, "skip first `n` lines of input")
flag.Parse()
flag.PrintDefaults()
}
and this is output :
-f string
load links list file (required)
-l n
skip first n lines of input
-t N
run N attempts in parallel threads (default 50)
i want hide from printdefaults -l and -t, how i can do this ?
There might be multiple ways of doing this. An easy one would be to use VisitAll:
func VisitAll(fn func(*Flag))
In the function you pass you can decide whether or not to output a flag based on any of the exported fields of Flag.
Example:
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "l" || f.Name == "t" {
return
}
fmt.Println("Flag: ", f)
})
Run it at: https://play.golang.org/p/rsrKgWeAQf

Groovy println prints empty string to console instead of the proper string

I'm parsing output for a test I'm running as a Gradle JavaExec task. I want to filter the output so that only errors are shown in stdout (I'm running the task from the Windows command line).
In a doLast{} block, I've parsed the OutputStream to a list of strings where each entry is a line:
ByteArrayOutputStream baos = new ByteArrayOutputStream()
String log = baos.toString()
List<String> logLines
logLines = new ArrayList<String>(Arrays.asList(log.split('\n')))
then iterated through the list, printing each line that starts with 'E' (for ERROR):
for (String entry : logLines){
if (entry.charAt(0) == 'E'){
println "First char == E"
println (entry)
}
}
println "Execution complete!"
My output prints the first two errors, but prints empty strings for all the rest:
First char == E
ERROR More info here
First char == E
ERROR More info here
First char == E
First char == E
First char == E
Execution complete!
Why does println(entry) print empty strings? Obviously entry is not an empty string, because it wouldn't get past the boolean condition if it's first character was empty.
#Roman had the answer: println(groovy.json.JsonOutput.toJson(entry)) revealed that carriage returns \r were being used in addition to new lines \n. Therefore the solution is to split by the regex '[\r\n]+' which will separate into an array of strings at each \n or \r\n

Expand passed arguments before printing with puts to virtual server

I am having trouble with an expect script not evaluating arguments. Everything in the puts ${file_id} block (simplified obviously) gets placed onto a virtual machine and is later used to for configuration. The block you see puts the same code into a local directory for me to see if things are working properly.
global env
set env(os1) [lindex $argv 0]
set env(scratch_repo) /tmp/yum.repo_[pid]
set file_id [ open ${env(scratch_repo)} "w"]
puts ${file_id} {
root_image=node-${env(os1)}
if {[string first r ${env(os1)}] == 0} {
create_node_byid 1 [string range ${env(os1)} 0 4]-64
} else {
create_node_byid 1 [string range ${env(os1)} 0 5]-64
}
}
Unfortunately, the log file looks exactly as above. The arguments are not being substituted properly and I can't figure out why. I've tried using regular variables, different syntax for referencing local and global variables but have had no luck getting this to work. Any thoughts?
As Etan Reisner pointed use double quotes in the puts command instead of braces, so that it will get replaced.
puts ${file_id} "
root_image=node-${env(os1)}
if {[string first r ${env(os1)}] == 0} {
create_node_byid 1 [string range ${env(os1)} 0 4]-64
} else {
create_node_byid 1 [string range ${env(os1)} 0 5]-64
}
"
Assuming env(os1) as Ubuntu, will produce the following content in the file
root_image=node-Ubuntu
if {-1 == 0} {
create_node_byid 1 Ubunt-64
} else {
create_node_byid 1 Ubuntu-64
}
Note : This will only do variable substitutions not evaluation of code as such. i.e. if-else commands won't be evaluated.

Resources