英文:
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)
}
}
或者,使用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)
}
}
英文:
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)
}
}
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)
}
}
答案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 "${TARGET/'$HOME'/$HOME}"
done < .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 "$TARGET" in
\#*)
# Skip comments.
;;
*)
rm -fr "${TARGET/'$HOME'/$HOME}"
;;
esac
done < .clean
If you need more compatibility i.e. it doesn't support ${PARAM/X/Y}
expansion method, just used sed anyway:
rm -fr "$(echo "$TARGET" | sed "s|$HOME|$HOME|")" ## No 'g'. I doubt it's sensible to have two `$HOME`'s.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论