skip to Main Content

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


  1. When you write the line to the file, you are adding a newline character:

    file.WriteString(line + "n")
    

    That’s where the empty newlines at the end of the file are coming from.

    Login or Signup to reply.
  2. The file ends with a n. The last element of strings.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:

        scanner := bufio.NewScanner(bytes.NewReader(data))
        for scanner.Scan() {
            line := scanner.Text()
            if line != userName {
                if _, err := file.WriteString(line + "n"); err != nil {
                    logger.Fatal("Failed to write user to open blacklist file %sn", err)
                }
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search