我们想要删除
^[
以及所有转义序列。
sed 无法工作并给我们这个错误:
$ sed 's/^[//g' oldfile > newfile; mv newfile oldfile;
sed: -e expression #1, char 7: unterminated `s' command
$ sed -i '' -e 's/^[//g' somefile
sed: -e expression #1, char 7: unterminated `s' command
您在寻找ansifilter吗?
你可以做两件事:输入文字转义符(在 bash 中:)
使用键盘输入:
sed 's/Ctrl-vEsc//g'
或者
sed 's/Ctrl-vCtrl-[//g'
或者您可以使用字符转义:
sed 's/\x1b//g'
或对于所有控制字符:
sed 's/[\x01-\x1F\x7F]//g' # NOTE: zaps TAB character too!
commandlinefu 给出正确答案,它会去除 ANSI 颜色以及移动命令:
sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"
ansi2txt 命令(kbtin 包的一部分)似乎在 Ubuntu 上完美地完成了这项工作。
我在寻找一种从手册页中删除额外格式的方法时偶然发现了这篇文章。 ansifilter 做到了,但它与预期的结果相去甚远(例如,所有先前的粗体字符都被重复,如
SSYYNNOOPPSSIISS
)。
对于该任务,正确的命令是
col -bx
,例如:
groff -man -Tascii fopen.3 | col -bx > fopen.3.txt
为什么这有效:(回应@AttRigh的评论)
groff
产生粗体字符,就像在打字机上一样:打印一个字母,用退格键向后移动一个字符(您无法擦除打字机上的文本),再次打印相同的字母以使字符更明显。因此,简单地省略退格键会产生“SSYYNNOOPPSSIISS”。 col -b
通过正确解释退格键修复了这个问题,引用手册:
-b 不输出任何退格键,仅打印写入每列位置的最后一个字符。
您可以使用以下命令删除所有不可打印的字符:
sed 's/[^[:print:]]//g'
sed
的方法,无需通过 -r
启用扩展正则表达式
sed 's/\x1B\[[0-9;]*[JKmsu]//g'
只是一个注释;假设您有一个这样的文件(此类行结尾是由
git
远程报告生成的):
echo -e "remote: * 27625a8 (HEAD, master) 1st git commit\x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: Current branch master is up to date.\x1b[K" > chartest.txt
在二进制中,这看起来像这样:
$ cat chartest.txt | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 1b | 1st git commit.|
00000030 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000040 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 |emote: .[K.remot|
00000050 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b |e: .[K.remote: .|
00000060 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000070 65 6d 6f 74 65 3a 20 43 75 72 72 65 6e 74 20 62 |emote: Current b|
00000080 72 61 6e 63 68 20 6d 61 73 74 65 72 20 69 73 20 |ranch master is |
00000090 75 70 20 74 6f 20 64 61 74 65 2e 1b 5b 4b 0a |up to date..[K.|
0000009f
可以看到,
git
这里在行尾(0x1b
)之前添加了序列0x5b
0x4b
0x0a
。
请注意 - 虽然您可以在 sed 中将
0x1b
与文字格式 \x1b
匹配,但您不能对 0x5b
执行相同操作,它代表左方括号 [
:
$ cat chartest.txt | sed 's/\x1b\x5b//g' | hexdump -C
sed: -e expression #1, char 13: Invalid regular expression
您可能认为可以使用额外的反斜杠
\
来转义表示形式 - 最终结果为 \\x5b
;但是虽然“通过了”-但它与预期的任何内容都不匹配:
$ cat chartest.txt | sed 's/\x1b\\x5b//g' | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 1b | 1st git commit.|
00000030 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000040 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 |emote: .[K.remot|
...
因此,如果你想匹配这个字符,显然你必须将其写为转义的左方括号,即
\[
- 其余的值可以使用转义的\x
表示法输入:
$ cat chartest.txt | sed 's/\x1b\[\x4b//g' | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 0a | 1st git commit.|
00000030 72 65 6d 6f 74 65 3a 20 0a 72 65 6d 6f 74 65 3a |remote: .remote:|
00000040 20 0a 72 65 6d 6f 74 65 3a 20 0a 72 65 6d 6f 74 | .remote: .remot|
00000050 65 3a 20 0a 72 65 6d 6f 74 65 3a 20 0a 72 65 6d |e: .remote: .rem|
00000060 6f 74 65 3a 20 43 75 72 72 65 6e 74 20 62 72 61 |ote: Current bra|
00000070 6e 63 68 20 6d 61 73 74 65 72 20 69 73 20 75 70 |nch master is up|
00000080 20 74 6f 20 64 61 74 65 2e 0a | to date..|
0000008a
Tom Hale 的回答留下了不需要的代码,但这是一个很好的工作基础。添加额外的过滤清除剩余的、不需要的代码:
sed -e "s,^[[[(][0-9;?]*[a-zA-Z],,g" \
-e "s/^[[[][0-9][0-9]*[@]//" \
-e "s/^[[=0-9]<[^>]*>//" \
-e "s/^[[)][0-9]//" \
-e "s/.^H//g" \
-e "s/^M//g" \
-e "s/^^H//" \
file.dirty > file.clean
由于这是在非 GNU 版本的 sed 上完成的,您可以在其中看到
^[
、^H
和 ^M
,因此我使用了 Ctrl-V ^>
实际上是克拉 (^) 和大于字符,而不是 Ctrl-<.
当时使用的是 TERM=xterm。
要删除 PCL 代码,请添加如下模式:
sed -e "s/^[[&()*][a-z]*[-+]*[0-9][0-9]*[A-Z]//" \
-e "s/^[[=9EZYz]//" \
file.dirty > file.clean
理想情况下,如果正则表达式与理解 ? 元字符的解释器一起使用,则第一个模式更好地表示为:
"s/^[[&()*][a-z]?[-+]?[0-9][0-9]*[A-Z]//" \
我一直使用的 bash 片段来去除(至少一些)ANSI 颜色:
shopt -s extglob
while IFS='' read -r line; do
echo "${line//$'\x1b'\[*([0-9;])[Km]/}"
done
我的回答
jenkins 在我们的日志中填充的这些奇怪的 ha:// URL 是什么?
有效地从 Jenkins 控制台日志文件中删除所有 ANSI 转义序列(它还处理 Jenkins 特定的 URL,这与此处不相关)。
我感谢并感谢 Marius Gedminas 和 pyjama 在制定最终解决方案方面做出的贡献。
这个简单的 awk 解决方案对我有用,试试这个:
str="happy $(tput setaf 1)new$(tput sgr0) year!" #colored text
echo $str | awk '{gsub("(.\\[[0-9]+m|.\\(..\\[m)","",$0)}1' #remove ansi colors