在Golang中引用一个文件并在每行前运行一个命令。

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

Source a file inside golang and run a command before each listed line

问题

在一个golang程序中,我想要引用一个文件(在这种情况下是.clean),它的内容如下:

$HOME/directory1
$HOME/directory1/.directory2
$HOME/directory3

然后在每个目录之前运行rm -rf命令。有人知道如何实现这个吗?

英文:

Inside a golang program i want to source a file (in this case its .clean) which would look like this

$HOME/directory1
$HOME/directory1/.directory2
$HOME/directory3

and then run the rm -rf command before each directory.
Does anyone know how to accomplish this?

答案1

得分: 3

你可以使用bufio.Scanner来实现这个功能。

我添加了粗体文本

> Scanner提供了一个方便的接口,用于读取数据,例如由换行符分隔的文本行文件。连续调用Scan方法将逐步遍历文件的“标记”,跳过标记之间的字节。标记的定义由类型为SplitFunc的拆分函数定义;默认的拆分函数将输入拆分为去除行终止符的行。此包中定义了用于将文件扫描为行、字节、UTF-8编码的符文和以空格分隔的单词的拆分函数。客户端也可以提供自定义的拆分函数。

使用os.RemoveAll()的示例:

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	f, err := os.Open(".clean")
	if err != nil {
		log.Fatal(err)
	}
	s := bufio.NewScanner(f)
	for s.Scan() {
		fmt.Println("Deleting:", s.Text())
		if err := os.RemoveAll(s.Text()); err != nil {
			log.Println(err)
		}
	}
	if err := s.Err(); err != nil {
		log.Fatal(err)
	}
}

Playground

或者,使用os/exec中的Cmd.Run()运行rm -rf

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func main() {
	f, err := os.Open("file.txt")
	if err != nil {
		log.Fatal(err)
	}
	s := bufio.NewScanner(f)
	for s.Scan() {
		fmt.Println("Deleting:", s.Text())
		cmd := exec.Command("rm", "-rf", s.Text())
		if err := cmd.Run(); err != nil {
			log.Println(err)
		}
	}
	if err := s.Err(); err != nil {
		log.Fatal(err)
	}
}

Playground

英文:

You can do this using a bufio.Scanner.

Bold text added by me.

>Scanner provides a convenient interface for reading data such as a file of newline-delimited lines of text. Successive calls to the Scan method will step through the 'tokens' of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. Split functions are defined in this package for scanning a file into lines, bytes, UTF-8-encoded runes, and space-delimited words. The client may instead provide a custom split function.

Example using os.RemoveAll():

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	f, err := os.Open(".clean")
	if err != nil {
		log.Fatal(err)
	}
	s := bufio.NewScanner(f)
	for s.Scan() {
		fmt.Println("Deleting:", s.Text())
		if err := os.RemoveAll(s.Text()); err != nil {
			log.Println(err)
		}
	}
	if err := s.Err(); err != nil {
		log.Fatal(err)
	}
}

Playground

Or, using Cmd.Run() from os/exec to run rm -rf:

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func main() {
	f, err := os.Open("file.txt")
	if err != nil {
		log.Fatal(err)
	}
	s := bufio.NewScanner(f)
	for s.Scan() {
		fmt.Println("Deleting:", s.Text())
		cmd := exec.Command("rm", "-rf", s.Text())
		if err := cmd.Run(); err != nil {
			log.Println(err)
		}
	}
	if err := s.Err(); err != nil {
		log.Fatal(err)
	}
}

Playground

答案2

得分: 0

而不是“引用”文件,你可以直接读取它:

while IFS= read TARGET; do
    rm -fr "${TARGET/'$HOME'/$HOME}"
done < .clean

你还可以添加一些检查,比如跳过注释:

while read TARGET; do  ## 显式地不更改 IFS 以排除前导和尾随空格。
    case "$TARGET" in
    \#*)
        # 跳过注释。
        ;;
    *)
        rm -fr "${TARGET/'$HOME'/$HOME}"
        ;;
    esac
done < .clean

如果你需要更多的兼容性,即它不支持 ${PARAM/X/Y} 扩展方法,仍然可以使用 sed:

rm -fr "$(echo "$TARGET" | sed "s|$HOME|$HOME|")"  ## 没有 'g'。我怀疑有两个 `$HOME` 是不明智的。
英文:

Instead of "sourcing" the file, you could instead just read it:

while IFS= read TARGET; do
    rm -fr &quot;${TARGET/&#39;$HOME&#39;/$HOME}&quot;
done &lt; .clean

You can also add checks to it like skipping comments:

while read TARGET; do  ## Explicitly do not change IFS to exclude leading and trailing spaces.
    case &quot;$TARGET&quot; in
    \#*)
        # Skip comments.
        ;;
    *)
        rm -fr &quot;${TARGET/&#39;$HOME&#39;/$HOME}&quot;
        ;;
    esac
done &lt; .clean

If you need more compatibility i.e. it doesn't support ${PARAM/X/Y} expansion method, just used sed anyway:

rm -fr &quot;$(echo &quot;$TARGET&quot; | sed &quot;s|$HOME|$HOME|&quot;)&quot;  ## No &#39;g&#39;. I doubt it&#39;s sensible to have two `$HOME`&#39;s.

huangapple
  • 本文由 发表于 2014年6月4日 19:48:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/24036583.html
匿名

发表评论

匿名网友

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

确定