【问题标题】:How to strip control characters when saving output to variable?将输出保存到变量时如何去除控制字符?
【发布时间】:2021-04-17 16:20:23
【问题描述】:

尝试从^[[1mfoo^[(B^[[m 中删除控制字符,例如^[[1m^[(B^[[m

$ cat test.sh
#! /bin/bash

bold=$(tput bold)
normal=$(tput sgr0)

printf "%s\n" "Secret:"
printf "$bold%s$normal\n" "foo"
printf "%s\n" "Done"
$ cat test.exp
#!/usr/bin/expect

log_file -noappend ~/Desktop/test.log

spawn ~/Desktop/test.sh
expect {
  -re {Secret:\r\n(.+?)\r\nDone} {
    set secret $expect_out(1,string)
  }
}
$ expect ~/Desktop/test.exp
spawn ~/Desktop/test.sh
Secret:
foo
Done
$ cat -e ~/Desktop/test.log
spawn ~/Desktop/test.sh^M$
Secret:^M$
^[[1mfoo^[(B^[[m^M$
Done^M$

【问题讨论】:

  • 来自所有输出,还是仅来自日志文件?

标签: tcl expect


【解决方案1】:

转义序列取决于 TERM 变量。你可以通过假装有一个哑终端来避免它们:

set env(TERM) dumb
spawn ~/Desktop/test.sh

这适用于提供的示例。从提供的信息中无法判断它是否适用于实际情况。这取决于程序是否真的使用 termcaps 来生成转义序列。

【讨论】:

    【解决方案2】:

    我在expect 中看不到任何方法来添加挂钩以在匹配/记录/等之前操作正在读取的数据。但是,您可以在管道中添加另一层,以在 expect 看到它之前通过调整您的 test.exp 从正在运行的实际程序输出的内容中去除 ANSI 转义:

    set csi_re [subst -nocommands {\x1B\\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]}]
    spawn sh -c "~/Desktop/test.sh | sed 's/$csi_re//g'"
    

    这使用sedtest.sh 的输出中去除与ANSI terminal CSI escape sequences 匹配的所有字符串。

    【讨论】:

    • 你也可以通过 regsub 在 Tcl 方面进行处理。
    • 这不会影响日志,这对 OP 来说似乎很重要。
    猜你喜欢
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2014-04-01
    • 2015-12-30
    相关资源
    最近更新 更多