有没有办法使用常见的 bash 命令解释/“执行”文件/行中的退格键?我有一个控制台程序,它打印一些内容,然后使用退格键删除它,最后写入最终结果。我真正想要的是最后的输出。
echo -e "Foo\b\b\bBar" | what_goes_here > test.log
我的 test.log 应该只包含“Bar”。我想这样做的一个问题是应该缓冲多少文本直到被视为真正打印......在我的情况下,“行缓冲”解释器就足够了。
大多数实用程序都有一个开关,它不会首先打印此类字符。但手头的实用程序没有这样的开关......
答案1
这就是col -b
目的:
$ printf 'a\bb\n' | col -b | od -tc
0000000 b \n
0000002
$ printf 'aaa\b\b\bbb\n' | col -b | od -tc
0000000 b b a \n
0000004
等价sed
的东西是这样的:
bs=$(printf '\b')
sed "s/^[^$bs]*/&\
\
/;:1
s/\n.\{0,1\}\(.*\n\)\([^$bs]\)/\2\
\1/;s/\(.\{0,1\}\)\n\(.*\n\)$bs/\
\1\2/;t1
s/\n//g"
追溯到真正的电传打字机 (tty) 时代,x\bx
有时会发现该序列表示粗体x
(x
在其自身上打字),x\b_
或_\bx
表示下划线x
( x̲
),x\b-
或-\bx
表示删除线 ( x̶
)。
处理这些问题的另一个有用命令是colcrt
命令。
$ printf '_\bfo\b_o\b_ bar b\b-a\b-z\b-\n' | colcrt
foo bar baz
---
另一种选择是将\b_
和转换\b-
为组合字符 U+0332 和 U+0336 的 Unicode:
这里假设 Unicode 区域设置 和zsh
,ksh93
或bash
:
$ printf 'f\b_o\b_o\b_ bar b\b-a\b-z\b-\n' | sed $'s/\b_/\u0332/g;s/\b-/\u0336/g'
f̲o̲o̲ bar b̶a̶z̶
(管道colcrt
或col -b
也处理x\bx
粗体)。
答案2
尝试sed
如果用于ksh93/zsh/bash
printf "Foo\b\b\bBar\n" | sed -e :a -e "s/.\{0,1\}"$'\b'"//;ta" > test.log
或更便携
printf "Foo\b\b\bBar\n" | sed -e :a -e "s/.\{0,1\}$(printf "\b")//;ta" > test.log
或 GNU sed:
printf "Foo\b\b\bBar\n" | gsed -re ":a;s/.?\x08//;ta" > test.log
注意:此方法将 '\b' 视为向后擦除而不是退格,因此如果 \b 后面的字符数小于 \b 的数量,则会出现差异。 (感谢@StephaneChazelas)