在Golang中运行awk的方法与实践
在Golang中运行awk的方法与实践 我正在尝试执行这段代码,但只得到错误信息
_, err := exec.Command("awk", '{gsub(/./,",",$0);print $0}', file, "| sponge", file).Output()
你能帮助我吗?
谢谢
感谢大家的建议,在你们的帮助下我成功解决了问题。
标准错误输出显示什么?很可能就是之前解释过的未知参数问题
_, err := exec.Command("awk", `{gsub(/\./",",$0);print $0}`, file, "| sponge", file).Output()
错误:退出状态 2
糟糕!
我不知道如何在这种情况下应用 stderr
我想要实现的是在一个巨型文件中将“.”替换为“,”,我找到的最快方法是使用 awk,但我无法从 golang 中运行它
epicteto:
但它没有将点替换为逗号
你考虑过使用 tr 吗?tr . ,
// 代码示例
func main() {
fmt.Println("hello world")
}
检查 Sprintf 调用的结果是否符合你在命令行中输入的形式。
但乍看之下,似乎你其中一条帖子缺少了逗号……我只是从那里复制的。
调试 awk 是你的工作,我不懂这个。
抱歉
output, err := exec.Command("bash", "-c", fmt.Sprintf(`awk '{gsub(/\./",",$0);print $0}' %[1]s | sponge %[1]s`, file)).Output()
它没有报错,但没有将点号替换为逗号,而这正是我希望代码实现的功能
衷心感谢您的帮助。
我执行了:
output, err: = exec.Command (“bash”, “-c”, fmt.Sprintf (`awk '{gsub (/\./",",$ 0); print $ 0}'% [1] s | sponge % [1] s`, fileAnalysis)). Output ()
它没有报错,但并未生效。
以下是我在状态栏应用中使用 awk 的方法:
首先将命令设置为字符串变量:
homeCmd := "df -Ph .| awk '/d*G/ {print $4}'"
然后在调用命令时需要通过 sh -c 来运行(在我的案例中还会捕获输出):
homeOut, err := exec.Command("sh", "-c", homeCmd).Output()
希望这能帮助阐明这个问题!
什么错误?
是因为错误使用 ' 导致的语法错误?还是因为 awk 无法将 | sponge 识别为参数?
exec.Command() 会绕过你的 shell 直接启动程序,你需要手动在 awk 和 sponge 之间建立管道。
另外 ' 用于字符而非字符串,你需要使用 " 并对内部引号进行转义,或者使用反引号包围的原始字符串(`{gsub(/./,",",$0);print $0}`)。
func main() {
fmt.Println("hello world")
}
不妨先来看看显而易见的解决方案:
/tmp % echo "Here. Is. A file." > foo
/tmp % sed -i.bak -e 's/\./,/g' foo
/tmp % cat foo
Here, Is, A file,
但如果你必须使用Go语言并且必须使用awk,关于你消失的逗号问题,NobbZ的说法是正确的。
你原来的代码是:
awk '{gsub(/\./",",$0);print $0}' %[1]s | sponge %[1]s
我通过在正则表达式/\./后面添加逗号获得了成功:
awk '{gsub(/\./, ",",$0);print $0}' %[1]s | sponge %[1]s
最简单的方法是使用 exec.(*Cmd).CombinedOutput(),至少在目前的情况下,这是侵入性最小的修复方案。
output, err := exec.Command(“awk”, `{gsub(/\./",",$0);print $0}`, file, “| sponge”, file).CombinedOutput()
fmt.Println(string(output))
fmt.Println(err)
结果可能会是这样:
# Created by newuser for 5.7.1
awk: cmd. line:1: fatal: cannot open file `| sponge' for reading (No such file or directory)
因为您运行的命令相当于在bash中执行以下命令:
awk '{gsub(/\./",",$0);print $0}' ~/.zshrc "| sponge" ~/.zshrc
你需要手动管理 *Cmd 的生命周期,并使用 exec.(*Cmd).Run()、exec.(*Cmd).StdoutPine() 和 exec.(*Cmd).StdinPipe() 将 awk 的 stdout 与 sponge 的 stdin 手动连接起来。
我实际上从未这样做过。
或者,你可以启动 bash 并执行类似以下操作:
output, err := exec.Command(bash, "-c", fmt.Sprintf(`awk '{gsub(/\./",",$0);print $0}' %[1]s | sponge %[1]s`, file)),Output()
不过我建议不要丢弃 stderr,而是使用 Run() 并准备附加到 stderr/stdout 的缓冲区,以确保在出现错误时能够显示输出,这样会更容易进行调试…


