我们要删除^[
和所有转义序列。
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
你在寻找安西过滤器吗?
您可以做的两件事:输入文字转义(在 bash 中:(
使用键盘输入:
sed 's/Ctrl-vEsc//g'
或者
sed 's/Ctrl-vCtrl-[//g'
或者,您可以使用字符转义:
sed 's/x1b//g'
或对于所有控制字符:
sed 's/[x01-x1Fx7F]//g' # NOTE: zaps TAB character too!
commandlinefu 给出了去除 ANSI 颜色和移动命令的正确答案:
sed "s,x1B[[0-9;]*[a-zA-Z],,g"
出于我的目的,我管理了以下内容,但这不包括所有可能的 ANSI 转义:
sed -r s/x1b[[0-9;]*m?//g
这将删除m
命令,但对于所有转义(如@lethalman注释所示(,请使用:
sed -r s/x1b[[^@-~]*[@-~]//g
另请参阅"https://stackoverflow.com/questions/7857352/python-regex-to-match-vt100-escape-sequences"。
还有一个常见转义序列表。
ansi2txt命令(kbtin包的一部分(似乎在Ubuntu上完美地完成了这项工作。
我没有足够的声誉来为 Luke H 给出的答案添加注释,但我确实想分享我一直用来消除所有 ASCII 转义序列的正则表达式。
sed -r 's~x01?(x1B(B)?x1B[([0-9;]*)?[JKmsu]x02?~~g'
在寻找一种从手册页中删除额外格式的方法时,我偶然发现了这篇文章。 AnsiFilter 做到了,但它远非预期的结果(例如,所有以前粗体字符都被复制,如 SSYYNNOOPPSSIISS
(。
对于该任务,正确的命令是 col -bx
,例如:
groff -man -Tascii fopen.3 | col -bx > fopen.3.txt
(来源(
为什么这样做:(回应@AttRigh的评论(
groff
生成粗体字符,就像在打字机上一样:打印一个字母,使用退格键将一个字符移回(您无法擦除打字机上的文本(,再次打印相同的字母以使字符更明显。因此,简单地省略退格会产生"SSYYNNOOPPSSIISS"。 col -b
通过正确解释退格键来解决此问题,请引用手册中的以下内容:
-b 不输出任何退格符,只打印写入每个列位置的最后一个字符。
您可以使用以下命令删除所有不可打印的字符:
sed 's/[^[:print:]]//g'
我为此构建了vtclean。它按顺序使用这些正则表达式去除转义序列(在正则表达式.txt中解释(:
// handles long-form RGB codes
^ 33](d+);([^ 33]+) 33\
// excludes non-movement/color codes
^ 33([[^a-zA-Z0-9@?]+|[()]).
// parses movement and color codes
^ 33([[]]([d?]+)?(;[d?]+)*)?(.)`)
它还执行基本的行编辑模拟,因此会解析退格键和其他移动字符(如左箭头键(。
只是一个注释;假设您有一个这样的文件(此类行尾由git
远程报告生成(:
echo -e "remote: * 27625a8 (HEAD, master) 1st git commitx1b[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
在这里添加了行尾 (0x0a
( 之前的序列0x1b
0x5b
0x4b
。
请注意 - 虽然您可以将0x1b
与 sed 中的文字格式x1b
匹配,但您不能对 0x5b
执行相同的操作,它表示左方括号[
:
$ cat chartest.txt | sed 's/x1bx5b//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
基于sed
的方法,没有-r
启用的扩展正则表达式
sed 's/x1B[[0-9;]*[JKmsu]//g'
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]//"
用来去除(至少一些(ANSI颜色的bash片段:
shopt -s extglob
while IFS='' read -r line; do
echo "${line//$'x1b'[*([0-9;])[Km]/}"
done
我的回答
詹金斯用什么奇怪的 ha://URL填充我们的日志?
有效地从 Jenkins 控制台日志文件中删除所有 ANSI 转义序列(它还处理特定于 Jenkins 的 URL,这些 URL 在这里无关紧要(。
我承认并感谢Marius Gedminas和睡衣在制定最终解决方案方面的贡献。
这个简单的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