Getting blank lines where lines were removed from a text file in Go

huangapple go评论67阅读模式
英文:

Getting blank lines where lines were removed from a text file in Go

问题

我有一个使用Go语言和cobra编写的CLI,其中一个命令是从文本文件中的用户名列表中删除特定的用户名。例如,我有一个文件中的用户名列表:

user1
user2
user3
user4
user5

这是我在cobra命令中的Go代码:

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 %s\n", 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 %s\n", err)
                }
            }
        }
    } else {
        if err != nil {
            logger.Fatal("Error stating blacklist %s\n", err)
        } else {
            logger.Fatal("--blacklist-file-path is a directory, not a file\n")
        }
    }
},

当我将userName设置为"user3"运行它时,生成的输出文件确实不包含"user3"。但是文件末尾会有一个空行""。如果我再运行该命令以删除另一个用户,它也会删除该用户,但生成的文件现在末尾会有两个空行,以此类推。

我可以通过将第22行更改为以下内容来避免空行:

if !(line == userName || line == "") {

我不明白为什么会出现这种情况。这看起来不合理。空行是从哪里来的?

我使用的是Ubuntu 20.04,Go版本是go1.16.5 linux/amd64,github.com/spf13/cobra版本是v1.5.0。

提前感谢您的任何见解。

英文:

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,
<pre>
user1
user2
user3
user4
user5
</pre>

Here's my Go code inside my cobra command,

Run: func(cmd *cobra.Command, args []string) {

	userBlacklist, _ := cmd.Flags().GetString(&quot;blacklist-file-path&quot;) 
	userName, _ := cmd.Flags().GetString(&quot;user-name&quot;)

    if info, err := os.Stat(userBlacklist); err == nil &amp;&amp; !info.IsDir() {
		data, err := ioutil.ReadFile(userBlacklist)
		if err != nil {
				logger.Fatal(&quot;Failed to read in blacklist: %s&quot;, err)
		}

		lines := strings.Split(string(data), &quot;\n&quot;)

		file, err := os.Create(userBlacklist)
		if err != nil {
				logger.Fatal(&quot;Could not overwrite blacklist file %s\n&quot;, err)
		}

		defer file.Close()

		for _, line := range lines {
			if line != userName{
				if _, err := file.WriteString(line + &quot;\n&quot;); err != nil {
					logger.Fatal(&quot;Failed to write user to open blacklist file %s\n&quot;, err)						
				}
			} 
		}
	} else {
		if err != nil {
			logger.Fatal(&quot;Error stating blacklist %s\n&quot;, err )
		} else {
			logger.Fatal(&quot;--blacklist-file-path is a directory, not a file\n&quot;)
		}
	}
},

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 == &quot;&quot;) {

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.

答案1

得分: 1

文件以\n结尾。strings.Split(string(data), "\n")的最后一个元素是空字符串。当处理最后一个元素时,程序将空字符串添加到文件末尾。

通过使用bufio.Scanner来解析行来修复:

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 %s\n", err)
        }
    }
}
英文:

The file ends with a \n. The last element of strings.Split(string(data), &quot;\n&quot;) 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 + &quot;\n&quot;); err != nil {
				logger.Fatal(&quot;Failed to write user to open blacklist file %s\n&quot;, err)
			}
		}
	}

答案2

得分: 0

当你将一行写入文件时,你添加了一个换行符:

file.WriteString(line + "\n")

这就是文件末尾出现空行的原因。

英文:

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

file.WriteString(line + &quot;\n&quot;)

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

huangapple
  • 本文由 发表于 2022年9月13日 02:23:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/73693689.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定