I have a CLI written in Go using cobra where one of the commands is to remove a specific username from a list of usernames in a text file. For example, I have a list of usernames in a file,
user1 user2 user3 user4 user5
Here’s my Go code inside my cobra command,
Run: func(cmd *cobra.Command, args []string) {
userBlacklist, _ := cmd.Flags().GetString("blacklist-file-path")
userName, _ := cmd.Flags().GetString("user-name")
if info, err := os.Stat(userBlacklist); err == nil && !info.IsDir() {
data, err := ioutil.ReadFile(userBlacklist)
if err != nil {
logger.Fatal("Failed to read in blacklist: %s", err)
}
lines := strings.Split(string(data), "n")
file, err := os.Create(userBlacklist)
if err != nil {
logger.Fatal("Could not overwrite blacklist file %sn", err)
}
defer file.Close()
for _, line := range lines {
if line != userName{
if _, err := file.WriteString(line + "n"); err != nil {
logger.Fatal("Failed to write user to open blacklist file %sn", err)
}
}
}
} else {
if err != nil {
logger.Fatal("Error stating blacklist %sn", err )
} else {
logger.Fatal("--blacklist-file-path is a directory, not a filen")
}
}
},
When I run it with, say, userName set to "user3" the resulting output file does indeed not have user3 in it. However it does have a blank line of "" at the end of the file. If I then run the command asking it to remove another user, it will remove that user too but the resulting file will now have two blank lines at the end, etc., etc.
I can prevent the blank lines by changing line 22 to be,
if !(line == userName || line == "") {
I don’t understand how this is happening. Doesn’t seem sensible? Where are the blank lines coming from?
I am on Ubuntu 20.04, Go version go1.16.5 linux/amd64, and github.com/spf13/cobra v1.5.0
Thanks in advance for any insight.
2
Answers
When you write the line to the file, you are adding a newline character:
That’s where the empty newlines at the end of the file are coming from.
The file ends with a
n
. The last element ofstrings.Split(string(data), "n")
is the empty string. The program adds the empty string to the end of the file when processing the last element.Fix by using bufio.Scanner to parse the lines: